Implementation of lower_bound on vector pairs
Asked Answered
H

4

14

I know we need to include some compare function in order to achieve this.

But not able to write for this one.

For example:

Elements of vector={(2,4),(4,2),(5,1),(5,3)}

to find=5

lower_bound() should return 2

code->

#define pp pair<int,int>

bool cmp(const pp &l,const pp &r) {
    return l.first < r.first;
}

int main() {
   vector<pp> v;
   sort(v.begin(), v.end(), cmp);
   int id=(int)(lower_bound(v.begin(), v.end(), ??) - v.begin());
}
Hiedihiemal answered 1/6, 2014 at 15:19 Comment(5)
I would suggest typedef std::pair<int, int> pp; instead of macro definition.Constraint
But macro definition works too!Hiedihiemal
ideone.com/M0PZPLHiedihiemal
@Hiedihiemal Yes, but it's not the appropriate way to do it. This is precisely what typedefs are for.Quadragesimal
@Hiedihiemal “Macro definition works too!” – No it does not, outside of your trivial example. This has been explained to death on here and elsewhere.Fonteyn
H
16

Pairs (just like tuples) compare lexicographically anyway. You don't need to define any special comparators for this.

And since you're using lower_bound you'll be searching for the first element that does not compare less than the val you're searching, so you should use a min value as the second pair element. To sum up, all can be done in "two" lines of code :

sort(v.begin(),v.end());
auto id = distance(v.begin(), lower_bound(v.begin(),v.end(), 
       make_pair(5, numeric_limits<int>::min())) );

Some Notes :

  1. Use std::distance to calculate the number of elements between two iterators
  2. The return type of std::distance is an unsigned type. Unless you need negative indexing (Python like syntax for "count from the end" indexes) it's a good practice to keep your indexes unsigned.
Hydrotropism answered 1/6, 2014 at 17:25 Comment(2)
Can you explain how numeric_limits<int>::min() works?Fernand
@KPMG numeric_limits<T> provides information on numerical types. min() is a static function returning the smallest number representable by T (here: T = int). Likewise, numeric_limits<T>::max() provides the largest number representable by the type T. These are, for example, very useful when writing functions looking for minima or maxima. I would guess that numeric_limits<int>::max() simply sets all the bits of an int to 1.Protestantism
C
7

Since you don't care about the second value of pp, just construct a temporary pp object with any value as the second element.

int id = std::lower_bound(v.begin(), v.end(), pp(5, 0), cmp) - v.begin();
Constraint answered 1/6, 2014 at 15:22 Comment(1)
Better to use std::numeric_limits<int>::min() instead of 0.Myke
K
3

I think you should compare the pairs as per definition of lower_bound So,

   typedef pair<int,int> pp;
   //...

   int id=(int)(lower_bound(v.begin(),v.end(), 
                pp(5,std::numeric_limits<int>::min())), //Value to compare
                [](const pp& lhs, const pp& rhs)       // Lambda
                {
                    return lhs < rhs ;                //  first argument < second
                }
                 ) - v.begin()
               );
Ketchup answered 1/6, 2014 at 15:31 Comment(0)
T
1

You can use lower_bound on vector of pairs with custom compare operator .

You need to pass four arguments in that case like this :-

  • it1 = iterator position from where to search

  • it2 = iterator position till where to search

lower_bound (it1 ,it2 , finding_element, your_comparator )

auto myComp = [&](pair<int,string> e1, pair<int,string> e2) {
if(e1.second!=e2.second)
    return e1.second<e2.second;
else
    return e1.first<e2.first;
};
 
void Show_sample_code()
{
    vector<pair<int,string>> data={{1, "sahil"}, {2, "amin"}};
    sort(data.begin(), data.end(), myComp);
    pair<int, string> p={1,"sahil"};
    auto it=lower_bound( data.begin(), data.end(), p, myComp ) ;
    if(it!=data.end())
         cout<<"found at index="<<distance(data.begin(), it)<<endl;
    else
    cout<<"notfound"<<endl;
return;
}
Termite answered 11/2, 2021 at 18:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.