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.

Updated on: 2025-03-27T14:47:12+05:30

74 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements
close