如果我有一个字符串向量,如何使用不区分大小写的比较对某个字符串进行二进制搜索?我想不出任何简单的方法。
答案 0 :(得分:3)
为std :: sort提供一个比较函数,用小写字母对容器进行排序(使用boost string algos来帮助),
然后在已排序的向量上执行二进制字符串,再次提供不区分大小写的比较操作来执行此操作。
使用lambda表达式确实有帮助
如果使用find,则不必先进行排序,但如果要进行频繁搜索并且设置非常大,则速度很慢。
编辑:这是示例
#include <boost/algorithm/string.hpp>
#include <algorithm>
::::
auto comp=[](const std::string& a, const std::string& b){
return boost::ilexicographical_compare
<std::string, std::string>(a,b);
});
std::sort(vs.begin(), vs.end(), comp);
std::binary_search(vs.begin(), vs.end(), value_to_search_for, comp);
如果你不打算对列表进行排序,那么相同的比较函数也可以用于std :: find。
TESTED
http://en.cppreference.com/w/cpp/algorithm/find
答案 1 :(得分:0)
您可以使用find
标头中的algorithm
来查找容器中的特定值,但我认为它不使用二进制搜索算法(没有先决条件对容器进行排序在将其传递给find
之前。可以找到更多详细信息here。
binary_search
还提供了algorithm
,再次提供了更多详细信息here。
答案 2 :(得分:0)
我认为你需要编写自己的比较函数,它将比较小写变体中的两个字符串。使用此函数,您可以对vector进行排序,然后通过这些比较器比较查询字符串。
答案 3 :(得分:0)
std::find
不支持谓词参数,因此您要查找的正确算法为std::find_if
。
std::find_if( vec.begin(), vec.end(), InsensitiveCompare("search string") );
...其中InsensitiveCompare
是一个函数,它返回true
以进行不区分大小写的比较。例如:
struct InsensitiveCompare
{
std::string comp;
InsensitiveCompare( std::string const &s ) : comp(s) {}
bool operator() ( std::string const &test ) const
{
// return true here if test compares with comp.
}
}
答案 4 :(得分:0)
使用find_if
来提供自定义谓词:
find_if (myvector.begin(), myvector.end(), MyPredicate);
http://www.cplusplus.com/reference/algorithm/find_if/
另请参阅此文章以获取有关编写可重用谓词的帮助: Making map::find operation case insensitive
答案 5 :(得分:0)
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <strings.h> // strncasecmp()
inline int icompare(std::string const& a, std::string const& b) {
size_t a_len = a.size(), b_len = b.size();
size_t cmp_len = std::min(a_len, b_len);
// strncasecmp() is a non-standard function, use the one available for your platform.
if(int r = strncasecmp(a.data(), b.data(), cmp_len))
return r;
return (a_len > b_len) - (a_len < b_len);
}
struct LessNoCase {
bool operator()(std::string const& a, std::string const& b) const {
return icompare(a, b) < 0;
}
};
template<class Iterator, class T>
Iterator binary_search_caseless(Iterator beg, Iterator end, T const& value) {
Iterator i = std::lower_bound(beg, end, value, LessNoCase());
return i != end && !icompare(*i, value)
? i // found
: end // not found
;
}
int main() {
char const* strings[] = {
"abc",
"def",
"ghi"
};
std::vector<std::string> v(
strings + 0,
strings + sizeof strings / sizeof *strings
);
// prepare for binary search
std::sort(v.begin(), v.end(), LessNoCase());
// do the binary search
std::cout << "index of 'abc' is " << binary_search_caseless(v.begin(), v.end(), "ABC") - v.begin() << '\n';
std::cout << "index of 'ABC' is " << binary_search_caseless(v.begin(), v.end(), "ABC") - v.begin() << '\n';
std::cout << "index of 'DEF' is " << binary_search_caseless(v.begin(), v.end(), "DEF") - v.begin() << '\n';
std::cout << "index of 'xyz' is " << binary_search_caseless(v.begin(), v.end(), "xyz") - v.begin() << '\n';
}
输出:
./test
index of 'abc' is 0
index of 'ABC' is 0
index of 'DEF' is 1
index of 'xyz' is 3
答案 6 :(得分:0)
如果您只需要知道这样的元素是否存在,请使用std :: binary_search。如果您需要访问该元素并知道它的位置,请使用std :: lower_bound。