Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
How to initialize multi-set with custom comparator in C++
In this article, we will learn how to initialize a std::multiset with a custom comparator in C++. A multiset is similar to a set, except that it allows duplicate elements. It stores elements in a sorted order based on a comparison function.
By default, elements are compared using the < (less-than) operator. However, with a custom comparator, we can define how elements should be compared. For example, if we define a custom comparator that sorts elements in descending order and insert the following elements into the multiset:
Input: 3 12 5 8 1 7 9 4 6
Output: {12, 9, 8, 7, 6, 5, 4, 3, 1}
We will explain how to implement and use a custom comparator in C++ to change the default sorting behavior, with an example to illustrate the process.
Initializing a Multiset with a Custom Comparator
To initialize a multiset with a custom comparator, we need to define a custom function or functor that specifies how elements should be compared. This comparator is then passed as a parameter to the multiset to control the sorting order.
Let's look at three common ways to define a custom comparator:
Using a Function Pointer
In this approach, we define a custom function that compares two elements and returns true if one should be ordered before the other. This function is then passed to the std::multiset constructor to control the sorting order.
Example
In this example, we create a function (customComparator) that sorts elements in descending order. The function is passed to the multiset constructor, which uses it to store and order the elements accordingly.
#include <iostream>
#include <set>
#include <functional>
using namespace std;
// Comparator function to compare elements in descending order
bool customComparator(int a, int b) {
return a > b; // Elements will be sorted in descending order
}
int main() {
// Initialize multiset with a custom comparator
multiset<int, function<bool(int, int)>> myMultiset(customComparator);
// Insert elements
myMultiset.insert(10);
myMultiset.insert(30);
myMultiset.insert(20);
myMultiset.insert(40);
// Display elements in sorted order
cout << "After inserting elements: " << endl;
for (auto element : myMultiset) {
cout << element << " ";
}
cout << endl;
return 0;
}
Below is the output that shows the elements displayed in descending order:
After inserting elements: 40 30 20 10
Time Complexity: Complexity:O(n log n), with each of the n insertions taking O(log n) due to the balanced tree structure.
Space Complexity: O(n), as the multiset stores n elements.
Using a Function Object (Functor)
In this approach, we define a class (functor) that overloads the () operator to implement the custom comparison logic. This functor is then passed to the std::multiset constructor to control the ordering of the elements
Example
In this example, we use a functor (CustomComparator) to compare elements in descending order. The functor is passed to the std::multiset constructor to control the ordering of elements.
#include <iostream>
#include <set>
using namespace std;
// Functor class to compare elements in descending order
class CustomComparator {
public:
bool operator()(int a, int b) const {
return a > b; // Elements will be sorted in descending order
}
};
int main() {
// Initialize multiset with a custom comparator (using functor)
multiset<int, CustomComparator> myMultiset;
// Insert elements
myMultiset.insert(10);
myMultiset.insert(30);
myMultiset.insert(20);
myMultiset.insert(40);
// Display elements in sorted order
cout << "After inserting elements: " << endl;
for (auto element : myMultiset) {
cout << element << " ";
}
return 0;
}
The output below shows the elements ordered in descending order:
After inserting elements: 40 30 20 10
Time Complexity: O(n log n) due to n insertions, each taking O(log n), and O(n) for iteration.
Space Complexity: O(n) because the multiset stores n elements.
Using a Lambda Expression
In this approach, we use a lambda expression to define a custom comparator inline. A lambda expression is an anonymous function that allows us to specify the comparison logic directly when initializing the multiset.
Example
In this example, we define a lambda function(comparator) that compares two integers in descending order. We then use this lambda as a custom comparator to initialize the multiset. The elements are then inserted and displayed in sorted order.
#include <iostream>
#include <set>
#include <functional>
int main() {
// Using lambda as a comparator
auto comp = [](const int& a, const int& b) { return a > b; };
std::multiset<int, decltype(comp)> myMultiset(comp);
// Add elements
myMultiset.insert({10, 30, 20, 40});
// Print the elements
std::cout << "After inserting elements: "<< std::endl ;
for (const auto& elem : myMultiset) {
std::cout << elem << " ";
}
return 0;
}
Below is the output showing the elements displayed in descending order:
After inserting elements: 40 30 20 10
Time Complexity: O(n log n) due to n insertions, each taking O(log n), and O(n) for iteration.
Space Complexity: O(n) because the multiset stores n elements.
Conclusion
In this article, we explained how to initialize a std::multiset with a custom comparator using three methods: function pointer, functor, and lambda expression. Each method allows us to define how the elements should be sorted based on our needs.