-1

I have a vector of pair "v" which is sorted according to the first value of the pair. Now I want to find out the lower bound of vector "v" according to the first value of the pair -- while finding the lower bound I want to ignore the second.

int pl; cin>>pl;
vector<pair<int,int>> v;
for (int i = 0; i < n; i++){
    int p,c; cin>>p>>c;
    v.push_back({p,c});
}

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

    
auto it = lower_bound(v.begin(),v.end(),pl);

cout<<(*it)<<endl;

I want to find the lower bound of pl in the vector pair,according to the 1st value of pairs.I'm a newbie so please elaborate

YSC
  • 38,212
  • 9
  • 96
  • 149

4 Answers4

3

I know your question is marked C++17, but for completeness: the C++20 solution could be to use the "projection" feature that the new ranges offer. E.g.:

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

int main() {
    auto v{std::vector<std::pair<int, int>>{
        {3, 1},
        {1, 2},
        {4, 5},
    }};

    std::ranges::sort(v);

    auto const pl{3};

    auto const it{std::ranges::lower_bound(v, pl, {},
        &decltype(v)::value_type::first)}; // last param = projection

    std::cout << (*it).second << '\n';
}

prints: 1

JHBonarius
  • 10,824
  • 3
  • 22
  • 41
1

Since you don't care about the second element of your pair, you can find a value whose lower bound is (pl, 0):

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

int main()
{
    std::vector<std::pair<int,int>> v;
    for (int i = 0; i < 11; i++)
    {
        v.push_back({ (17*i) % 59, (i*i) % 13});
    }

    std::sort(v.begin(),v.end());
    auto const it = std::lower_bound(v.begin(), v.end(), std::make_pair(11, 0)); // pl=11 in this example
    
    std::cout << "(" << it->first << ", " << it->second << ")\n"; // (17, 1)
}

Live demo

This works because std::pair::operator< is defined such that

(0,0) < (0,1) < (1,0) < (1,1)
YSC
  • 38,212
  • 9
  • 96
  • 149
1

You can pass a custom comparator to std::lower_bound, so long as it is consistent with your sort order.

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

bool first_less(std::pair<int, int> lhs, int rhs) {
    return lhs.first < rhs;
}

int main() {
    std::vector<std::pair<int, int>> v{
        {3, 1},
        {1, 2},
        {4, 5},
    };
    auto pl = 3;

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

    auto it = std::lower_bound(v.begin(), v.end(), pl, first_less);

    std::cout << it->second << '\n';
}

See it live

Caleth
  • 52,200
  • 2
  • 44
  • 75
0

JHBonarius' answer applies to C++17 too, as long as you are ok with using Range-v3:

#include <iostream>
#include <iterator>
#include <vector>
#include <utility>
#include <range/v3/algorithm/lower_bound.hpp>

int main() {
    std::vector<std::pair<int,int>> v{{0,3}, {0,2}, {1,1}, {1,2}};

    auto constexpr first = &decltype(v)::value_type::first;

    auto itFor0 = ranges::lower_bound(v, 0, std::less<>{}, first);
    auto itFor1 = ranges::lower_bound(v, 1, std::less<>{}, first);

    std::cout << std::distance(std::begin(v), itFor0) << std::endl; // 0
    std::cout << std::distance(std::begin(v), itFor1) << std::endl; // 2
}
Enlico
  • 23,259
  • 6
  • 48
  • 102