TheDeveloperBlog.com

Home | Contact Us

C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML

C++ algorithm equal_range() function

C++ algorithm equal_range() function with c++ tutorial for beginners and professionals with examples on adjacent_find(),any_of(), copy(), copy_if(), count(), count_if(), equal(), find(), find_end(), find_first_of(), find_if(), find_if_not(), for_each() etc.

<< Back to CPP

C++ Algorithm equal_range()

C++ Algorithm equal_range() function is the version of binary search. This function is used to return the lower bound and upper bound of the sub range that includes all the elements equivalent to val in the range [first, last).

Where sub range is defined by two iterators, one pointing to the first element that is not less than val and another pointing to the first element greater than val.

  • The first version uses operator < to compare the elements and the second version uses the given comparison function i.e. comp.
  • The range [first, last) must be partitioned with respect to comparison with val, i.e. it must satisfy all of the following conditions:
    • partitioned with respect to element < val or comp(element, val)
    • partitioned with respect to !(val < element) or !comp(val, element)
    • for all elements, if element < val or comp(element, val) is true then !(val < element) or !comp(val, element) is also true.

Syntax

default (1)      template <class ForwardIterator, class T>
                       pair<ForwardIterator,ForwardIterator>
                         equal_range (ForwardIterator first, ForwardIterator last, const T& val);

custom (2)     template <class ForwardIterator, class T, class Compare>
                      pair<ForwardIterator,ForwardIterator>
                       equal_range (ForwardIterator first, ForwardIterator last, const T& val,
                          Compare comp); 

Parameter

first: A forward iterator pointing to the first element in the range to be searched.

last: A forward iterator pointing to the past last element in the range to be searched.

comp: A user-defined binary predicate function that accepts two arguments and returns true if the two arguments are in order otherwise, it returns false. It follows the strict weak ordering to order the elements.

val: A value of the upper bound to compare the elements in the range.

Return value

It returns two iterators, one pointing to the first element that is not less than val and another pointing to the first element greater than val.

If no such element is found then it returns last.

Complexity

On average, complexity is logarithmic in the distance between first and last: performs up to 2*log2 (N) + 1 element comparisons Where N = last - first.

Data races

The object in the range [first, last) are accessed.

Exceptions

This function throws an exception if either an element comparison or an operation on iterator throws an exception.

Please note that invalid parameters cause an undefined behavior.

Example 1

Let's see the simple example to demonstrate the use of equal_range():

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
  vector<int> v = {3, 1, 4, 2, 5};

  sort(v.begin(), v.end());

  auto result = equal_range(v.begin(), v.end(), 3);

  cout << "Lower Bound of 3 is: "<<*result.first << endl;
  cout << "Upper Bound of 3 is: "<<*result.second << endl;
  
  return 0;
}

Output:

Lower Bound of 3 is: 3
Upper Bound of 3 is: 4

Example 2

Let's see another simple example to compare the elements using operator<:

#include <algorithm>
#include <vector>
#include <iostream>
 
using namespace std;
 
struct S
{
    int number;
    char name;
 
    S ( int number, char name  )
        : number ( number ), name ( name )
    {}
 
    // only the number is relevant with this comparison
    bool operator< ( const S& s ) const
    {
        return number < s.number;
    }
};
 
 
int main()
{
    // note: not ordered, only partitioned w.r.t. S defined below
    vector<S> vec = { {1,'A'}, {2,'B'}, {2,'C'}, {2,'D'}, {4,'G'}, {3,'F'} };
 
    S value ( 2, '?' );
 
    auto p = equal_range(vec.begin(),vec.end(),value);
 
    for ( auto i = p.first; i != p.second; ++i )
        cout << i->name << ' ';
        
        return 0;
}

Output:

B C D

In the above example, operator < is used to compare the elements and returns all the elements in the range which is equal to 2.

Example 3

Let's see another simple example to compare the elements using comparison function:

#include <algorithm>
#include <vector>
#include <iostream>

using namespace std;
 
struct S
{
    int number;
    char name;
 
    S ( int number, char name  )
        : number ( number ), name ( name )
    {}
 
    // only the number is relevant with this comparison
    bool operator< ( const S& s ) const
    {
        return number < s.number;
    }
};
 
struct Comp
{
    bool operator() ( const S& s, int i )
    {
        return s.number < i;
    }
 
    bool operator() ( int i, const S& s )
    {
        return i < s.number;
    }
};
 
int main()
{
    // note: not ordered, only partitioned w.r.t. S defined below
    vector<S> vec = { {1,'A'}, {2,'B'}, {2,'C'}, {2,'D'}, {4,'G'}, {3,'F'} };
 
    auto p = equal_range(vec.begin(),vec.end(),2,Comp());
 
    for ( auto i = p.first; i != p.second; ++i )
        cout << i->name << ' ';
        
        return 0;
}

Output:

B C D

Example 4

Let's see another simple example:

#include <iostream>
#include <vector>
#include <algorithm>
 
using namespace std;
 
int main()
{
  int a[] = {2, 3, 5, 6, 7, 7, 7,  8, 9, 10};
  vector<int> v(a, a+10);
  cout <<"\nHere are the contents of v:\n";
  for (vector<int>::size_type i=0; i<v.size(); i++)
    cout <<v.at(i)<<" ";
 
  pair<vector<int>::iterator, vector<int>::iterator> bounds;
 
  bounds = equal_range(v.begin(), v.end(), 3);
  if (bounds.first != v.end())
    cout <<"\nLower bound of 3 in v = "<<*bounds.first;
  if (bounds.first != v.end())
    cout <<"\nUpper bound of 3 in v = "<<*bounds.second;
 
  bounds = equal_range(v.begin(), v.end(), 4);
  if (bounds.first != v.end())
    cout <<"\nLower bound of 4 in v = "<<*bounds.first;
  if (bounds.first != v.end())
    cout <<"\nUpper bound of 4 in v = "<<*bounds.second;
 
  bounds = equal_range(v.begin(), v.end(), 5);
  if (bounds.first != v.end())
    cout <<"\nLower bound of 5 in v = "<<*bounds.first;
  if (bounds.first != v.end())
    cout <<"\nUpper bound of 5 in v = "<<*bounds.second;
 
  bounds = equal_range(v.begin(), v.end(), 7);
  if (bounds.first != v.end())
    cout <<"\nLower bound of 7 in v = "<<*bounds.first;
  cout <<"\nThis is the first of the three 7's, since the value "
         "before this 7 is "<<*(bounds.first-1)<<".";
  if (bounds.first != v.end())
    cout <<"\nUpper bound of 7 in v = "<<*bounds.second;
 
  bounds = equal_range(v.begin(), v.end(), 0);
  if (bounds.first != v.end())
    cout <<"\nLower bound of 0 in v = "<<*bounds.first;
  if (bounds.first != v.end())
    cout <<"\nUpper bound of 0 in v = "<<*bounds.second;
 
  bounds = equal_range(v.begin(), v.end(), 15);
  if (bounds.first != v.end())
    cout <<"\nLower bound of 15 in v = "<<*bounds.first;
  if (bounds.first != v.end())
    cout <<"\nUpper bound of 15 in v = "<<*bounds.second;
  cout <<"\nNote that both the lower and upper bound locations "
         "\nof 15 are the end (one-past-the-last) vector position.";
 
  return 0;
}

Output:

Here are the contents of v:
2 3 5 6 7 7 7 8 9 10 
Lower bound of 3 in v = 3
Upper bound of 3 in v = 5
Lower bound of 4 in v = 5
Upper bound of 4 in v = 5
Lower bound of 5 in v = 5
Upper bound of 5 in v = 6
Lower bound of 7 in v = 7
This is the first of the three 7's, since the value before this 7 is 6.
Upper bound of 7 in v = 8
Lower bound of 0 in v = 2
Upper bound of 0 in v = 2
Note that both the lower and upper bound locations 
of 15 are the end (one-past-the-last) vector position. 

Next TopicC++ Algorithm




Related Links:


Related Links

Adjectives Ado Ai Android Angular Antonyms Apache Articles Asp Autocad Automata Aws Azure Basic Binary Bitcoin Blockchain C Cassandra Change Coa Computer Control Cpp Create Creating C-Sharp Cyber Daa Data Dbms Deletion Devops Difference Discrete Es6 Ethical Examples Features Firebase Flutter Fs Git Go Hbase History Hive Hiveql How Html Idioms Insertion Installing Ios Java Joomla Js Kafka Kali Laravel Logical Machine Matlab Matrix Mongodb Mysql One Opencv Oracle Ordering Os Pandas Php Pig Pl Postgresql Powershell Prepositions Program Python React Ruby Scala Selecting Selenium Sentence Seo Sharepoint Software Spellings Spotting Spring Sql Sqlite Sqoop Svn Swift Synonyms Talend Testng Types Uml Unity Vbnet Verbal Webdriver What Wpf