How to initialize multi-set with custom comparator in C++

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.

Nishu Kumari
Nishu Kumari

Technical Content Engineer

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

422 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements