我有pairs
的向量。假设它是这样的:
vector<pair<int,int>> vec = { {1,12}, {1,5}, {1,6}, {1,9}, {3,9}, {3,11}, {3,13}, {3,4}, {5,9}, {5,91}, {13,8}, {16,8}, {20,8}, {20,81} };
pairs
按第一个元素排序。
给定pair
,我需要找到向量中最后一个pair
的索引,其第一个元素小于或等于给定对的第一个元素。如果最后pair
,其他对位于其左侧,并且第一个元素的值相同,我需要所有这些对中的第一个:
<4,10> => 4 (vec[4] is <3,9>, the elements with the largest first value less than or equal to 4 are those with first element as 3, and there are 4 pairs with a 3 in the first element, at indices 4-7, so return the first of those pairs)
<0,10> => -1, since no element exists to its right.
<1,6> => 0 (vec[0] is <1,12>. There is no pair whose first element is less than 1, and there are 4 pairs, including <1,6> whose first element is 1. So we need the first of these 4 pairs.)
<23,81> => 12 (vec[12] is <20,8>)
条件:我只需要使用标准算法,例如upper_bound
,binary_search
和lower_bound
。我试过这个,但是它失败了:
vector<pair<int,int>> vec = { {1,12}, {1,5}, {1,6},{1,9}, {3,9}, {3,11}, {3,13}, {3,4}, {5,9}, {5,91}, {13,8}, {16,8}, {20,8}, {20,81} };
auto i = std::lower_bound(vec.begin(), vec.end(), make_pair<int,int>(4,10),
[](const pair<int,int>& f1, const pair<int,int>& f2) { return f1.first < f2.first; });
cout << i-vec.begin();
答案 0 :(得分:5)
既然你想要第一对,你可能想要结合下限和上限?
#include <algorithm>
#include <vector>
#include <utility>
#include <iostream>
using namespace std;
int main()
{
vector<pair <int,int> > vec = { {1,12}, {1,5}, {1,6}, {1,9}, {3,9}, {3,11}, {3,13}, {3,4}, {5,9}, {5,91}, {13,8}, {16,8}, {20,8}, {20,81} };
auto u_it = std::upper_bound(vec.begin(), vec.end(), make_pair<int,int>(4, 10),
[](const pair<int,int>& f1, const pair<int,int>& f2) { return f1.first < f2.first; });
if(u_it == vec.begin())
cout << "-1\n";
auto l_it = std::lower_bound(vec.begin(), u_it, *prev(u_it),
[](const pair<int,int>& f1, const pair<int,int>& f2) { return f1.first < f2.first; });
cout << l_it - vec.begin() << "\n";
return 0;
}
输出:
Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall -std=c++0x main.cpp
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out
4
PS - 在WhozCraig评论后更新答案:
你想使用
it = std::upper_bound(beg,end)
来找到第一个严格更大的元素,如果它回答非开始,那么使用std::lower_bound(beg,it)
来找到其值被拉的元素的最低匹配序数来自(it-1)
。
现在答案满足您提供的所有 测试用例(我在这里没有显示)。希望有所帮助! :)
附录:
参考std::lower_bound,std::upper_bound和std::prev。请注意std::lower_bound
调用如何使用std::make_pair
而不使用初始化列表,以便让编译器发挥作用并解析deduce the type。
答案 1 :(得分:0)
std::lower_bound
返回第一个项大于或等于给定值
你需要
+1
到std::lower_bound
-1
到std::lower_bound
找到值(或者你可以使用std::upper_bound
)
再次使用std::lower_bound
找到合适的对
例如
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int my_find(const vector<pair<int,int>>& vec, int value){
auto comparer = [](const pair<int,int>& f1, int value) { return f1.first < value; };
auto i = std::lower_bound(vec.begin(), vec.end(), value+1, comparer);
if(i==vec.begin()){return -1;}
i = std::lower_bound(vec.begin(), vec.end(), (i-1)->first, comparer);
return i-vec.begin();
}
int main(){
vector<pair<int,int>> vec = { {1,12}, {1,5}, {1,6},{1,9}, {3,9}, {3,11}, {3,13}, {3,4}, {5,9}, {5,91}, {13,8}, {16,8}, {20,8}, {20,81} };
cout << my_find(vec,-1) << '\n';
cout << my_find(vec,3) << '\n';
cout << my_find(vec,10) << '\n';
cout << my_find(vec,100) << '\n';
}
顺便说一下,您不需要pair
提供lower_bound
如果您只使用lower_bound
,则只需要一个比较器