您在寻找std::lower_bound
,std::upper_bound
和std::equal_range
,它们需要一个输入范围,一个搜索值和一个可选的比较器,并要求根据比较器对范围进行排序。
为了您的具体的例子,我会使用std::lexicographical_compare
的比较:
#include <algorithm>
#include <iterator>
struct IdCmp
{
bool operator()(const Foo & lhs, const Foo & rhs) const
{
return std::lexicographical_compare(std::begin(lhs.id), std::end(lhs.id),
std::begin(rhs.id), std::end(rhs.id));
}
};
int main()
{
Foo a[100]; // populate
Foo b = make_needle();
auto p = std::equal_range(std::begin(a), std::end(a), b, IdCmp());
/* The elements with key equal to that of b are in [p.first, p.second). */
}
如果你希望能够直接搜索字符串,你的比较必须是可调用的异质同一个Foo
参数和一个字符串参数。例如:
struct IdCmp
{
bool operator()(const Foo & lhs, const Foo & rhs) const
{
return std::lexicographical_compare(std::begin(lhs.id), std::end(lhs.id),
std::begin(rhs.id), std::end(rhs.id));
}
bool operator()(const Foo & lhs, const char * id) const
{
return std::lexicographical_compare(std::begin(lhs.id), std::end(lhs.id),
id, id + 8);
}
bool operator()(const char * id, const Foo & rhs) const
{
return std::lexicographical_compare(id, id + 8,
std::begin(rhs.id), std::end(rhs.id));
}
};
现在您可以搜索:
std::lower_bound(std::begin(a), std::end(a), "ABCD1234", IdCmp())
为'find_if'接口是无用的二分查找。如果这是一场比赛,那很好。但是如果谓词表示它不匹配,那么搜索应该在下一个当前点之前还是之后查找? – 2014-11-23 20:51:45
还有一个明智的方向吗?假设条件是'isPrime(int x)',第一个值'x'是100.现在呢? – MSalters 2014-11-24 11:12:32
也许接口不完全一样,但返回一个int指示方向。 – user877329 2014-11-24 11:18:13