I have
std::vector<std::string> vec;
std::string myString;
我需要查找vec
中是否包含不区分大小写的字符串myString
。
我知道可以使用
find(vec.begin(), vec.end(), myString) != vec.end())
回答问题“myString是否在vec中?”需要进行区分大小写的比较。我需要进行不区分大小写的比较。
位置并不重要,我只想知道myString是否在vec中。
I have
std::vector<std::string> vec;
std::string myString;
我需要查找vec
中是否包含不区分大小写的字符串myString
。
我知道可以使用
find(vec.begin(), vec.end(), myString) != vec.end())
回答问题“myString是否在vec中?”需要进行区分大小写的比较。我需要进行不区分大小写的比较。
位置并不重要,我只想知道myString是否在vec中。
std::vector<std::string> vec = {"ALF", "B"};
std::string toSearch = "Alf";
auto itr = std::find_if(vec.begin(), vec.end(),
[&](auto &s) {
if ( s.size() != toSearch.size() )
return false;
for (size_t i = 0; i < s.size(); ++i)
if (::tolower(s[i]) == ::tolower(toSearch[i]))
return true;
return false;
}
);
if ( itr != vec.end()) {
std::cout << *itr << std::endl;
}
if (std::tolower(s[i]) != std::tolower(newServerName[i]))
return true;
return false;
因此,请更改比较并交换返回值。否则所有具有匹配第一个字符的字符串都被认为是相等的... - ur.或者,对于一个更小且易于阅读的解决方案,可以考虑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));
您需要使用std::find_if
并提供自定义比较器。为了实现不区分大小写的比较,建议将要比较的两个字符串转换为相同的大小写:小写或大写。这将导致以下代码:
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); });
});
myString
的任何匹配项,则将返回vec.end()
,您可以对该迭代器执行任何操作(包括与vec.end()
进行比较以知道是否找到了字符串)。vec.end()
进行简单比较,也可以计算出现次数(或其他任何操作)。 - Reritostd::toupper(std::string&)
这个函数,它只接受一个字符。 - marcinjtemplate <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
}
}
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();
std::tolower
接受一个字符而不是 std::string
。 - marcinj由于 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;
}