我有
std::vector<std::string> vec;
std::string myString;
我需要使用不区分大小写的comaprisons了解myString
是否在vec
。
我知道我可以使用
find(vec.begin(), vec.end(), myString) != vec.end())
回答问题“vec中是myString吗?”但这将进行区分大小写的比较。我需要不区分大小写的比较。
这个位置并不重要,我只是想知道myString是否在vec中。
答案 0 :(得分:4)
您需要使用std :: tolower和std :: find_if:
function momentToDate(input) { // Do NOT use the result to anything else than passing it into globalize
var res = new Date(input.year(), input.month(), input.date(), input.hour(), input.minute(), input.seconds(), input.milliseconds());
var offset = input.utcOffset();
res.getTimezoneOffset = function() {
return offset;
}
return res;
}
答案 1 :(得分:3)
您需要使用std::find_if
并提供自定义比较器。为了实现不区分大小写的比较,我建议您将要比较的两个字符串转换为常见情况:lower或upper。这将产生如下代码:
auto ret = std::find_if(vec.begin(), vec.end(),
[&myString](const std::string& s) {
if (s.size() != myString.size())
return false;
return std::equal(s.cbegin(), s.cend(), myString.cbegin(), myString.cend(), [](auto c1, auto c2) { return std::toupper(c1) == std::toupper(c2); });
});
如果没有找到vec.end()
,则返回一个迭代器myString
。您可以使用该迭代器做任何事情(包括将其与vec.end()
进行比较以了解您是否找到了您的字符串)。
奖励:在Coliru
上运行最少示例答案 2 :(得分:3)
或者,对于很多更小且更易于阅读的解决方案,Boost!
// #include <algorithm>
// #include <boost/algorithm/string/predicate.hpp>
const auto it = std::find_if(
std::begin(vec),
std::end(vec),
[&myString](const auto& str) { return boost::iequals(myString, str); }
);
const bool found = (it != std::end(vec));
答案 3 :(得分:2)
您可以使用std::find_if
,内嵌lambda和std::tolower
进行比较:
//Computing the lower version of mystring
std::string my_string_lower;
my_string_lower.reserve(mystring.size());
std::transform(mystring.begin(), mystring.end(), std::back_inserter(my_string_lower), ::tolower);
// Checking if it is exist in the vector:
auto is_exist = std::find_if(vec.begin(), vec.end(), [&my_string_lower](std::string item){
//Transform the each vector item to lower temporally
std::transform(item.begin(), item.end(), item.begin(), ::tolower);
return mystring==item;
}) != vec.end();
如果您要在字符串的同一个字符中多次搜索,那么如果您计算一次它会更好:
//Computing the lower version of the whole vector
std::vector<std::string> vec_lower;
vec_lower.reserve(vec.size());
std::transform(vec.begin(), vec.end(), std::back_inserter(vec_lower),[](std:string item){
std::transform(item.begin(), item.end(), item.begin(), ::tolower);
return item;
});
//Computing the lower version of mystring
std::string my_string_lower;
my_string_lower.reserve(mystring.size());
std::transform(mystring.begin(), mystring.end(), std::back_inserter(my_string_lower), ::tolower);
// Checking if it is exist in the lower version of the vector:
auto is_exist = std::find_if(vec_lower.begin(), vec_lower.end(), [&my_string_lower](const std::string& item){
return mystring==item;
}) != vec_lower.end();
答案 4 :(得分:1)
template <class T>
long VecFindIgnoreCase( const std::vector< T >& vec, const std::string& sFind ) {
return VecFindIgnoreCase( vec, sFind.c_str() );
}
template <class T>
long VecFindIgnoreCase( const std::vector< T >& vec, const char* sFind )
{
for ( std::vector< T >::const_iterator iter = vec.begin(); iter != vec.end(); ++iter )
if ( _stricmp( (*iter).c_str(), sFind ) == 0 )
return (long)std::distance( vec.begin(), iter );
return -1;
}
template <class T>
long VecFindIgnoreCase( const std::vector< T >& vec, const std::wstring& sFind ) {
return VecFindIgnoreCase( vec, sFind.c_str() );
}
template <class T>
long VecFindIgnoreCase( const std::vector< T >& vec, const wchar_t* sFind )
{
for ( std::vector< T >::const_iterator iter = vec.begin(); iter != vec.end(); ++iter )
if ( _wcsicmp( (*iter).c_str(), sFind ) == 0 )
return (long)std::distance( vec.begin(), iter );
return -1;
}
使用:
#include <string>
#include <vector>
void TestCode()
{
std::vector< std::string > strvecA;
std::vector< std::wstring > strvecW;
strvecA.push_back("abc");
strvecA.push_back("def");
strvecA.push_back("ghi");
strvecW.push_back(L"abc");
strvecW.push_back(L"def");
strvecW.push_back(L"ghi");
long ind;
ind = VecFindIgnoreCase( strvecA, "ABC" ); // ind = 0 found
ind = VecFindIgnoreCase( strvecA, "ghI" ); // ind = 2 found
ind = VecFindIgnoreCase( strvecA, "Xyz" ); // ind = -1 not found
ind = VecFindIgnoreCase( strvecW, L"aBc" ); // ind = 0 found
ind = VecFindIgnoreCase( strvecW, L"DEF" ); // ind = 1 found
ind = VecFindIgnoreCase( strvecW, L"xyZ" ); // ind = -1 not found
std::string sFind( "mno" );
if ( (ind = VecFindIgnoreCase( strvecA, sFind )) >= 0 ) {
// found at strvecA[ind]
} else {
// not found
}
}
答案 5 :(得分:0)
由于std::find
的性能比std::count
好,所以我要实现一个函数模板在std::vector
中搜索:
template <class Iterator>
Iterator Find(Iterator first, Iterator last, const char *value)
{
while (first != last)
{
if (StrCmpIA((*first).c_str(), value) == 0)
{
return first;
}
first++;
}
return last;
}
现在你可以像这样使用模板函数:
vector<string> vecStr = {"ali", "reza", "hamid", "saeed"};
if (Find(vecStr.begin(), vecStr.end(), "saeeD") != vecStr.end())
{
cout << "found" << endl;
}
else
{
cout << "not found" << endl;
}