我需要通过不区分大小写的比较从矢量列表中找到字符串。如果没有使用Boost,是否有一些简单的解决方案?
我为区分大小写的搜索编写的代码是:
std::map<std::string, std::string>::const_iterator it;
if (map.end() != (it = map.find(mKey)))
// if word matches
通过一个答案建议我使用find_if
并获得以下异常。它在特定值下给出以下错误
my_map1["$$HYPHEN{{a"] = "-";
使用lexicographical_compare
尝试了代码:
std::map<std::string, std::string> map1;
std::map<std::string,
std::string,
bool(*)(const std::string&, const std::string&)>
my_map_temp(case_insensitive_string_cmp);
my_map_temp["$$HYPHEN--a"] = "foo";
my_map_temp["$$HYPHEN{{a"] = "foo1";
while (my_map_temp.end() != my_map_temp.find("$$HYPHEn--a"))
{
std::cout << my_map_temp["hellOOOO"] << std::endl;
}
但在这种情况下,如何将map1
值复制到my_map_temp
?
答案 0 :(得分:3)
std::map::find
依赖于地图的内部排序。如果要使用此方法进行搜索,则需要使用不区分大小写的比较函数构建映射,也就是说,映射是不区分大小写的WRT键。
这可以通过利用std::lexicographical_compare
算法轻松完成,并将其与不区分大小写的元素进行比较:
#include <cctype>
#include <algorithm>
#include <string>
bool case_insensitive_cmp(char lhs, char rhs)
{
return std::toupper(lhs) < std::toupper(rhs);
}
bool case_insensitive_string_cmp(const std::string& lhs,
const std::string& rhs)
{
return std::lexicographical_compare(lhs.begin(),
lhs.end(),
rhs.begin(),
rhs.end(),
case_insensitive_cmp);
}
然后,使用不区分大小写的字符串比较函数创建映射:
std::map<std::string,
std::string,
bool(*)(const std::string&, const std::string&)>
my_map(case_insensitive_string_cmp);
my_map["Helloooo"] = "foo";
my_map["HELLOOOO"] = "bar";
std::cout << my_map["hellOOOO"] << std::endl;
如果您希望地图具有标准的,区分大小写的行为,但又想要执行不区分大小写的搜索,那么您需要将std::find_if
与合适的谓词一起使用。但是在这里你失去了地图的O(logN)查找的优势。
以下是标准地图中不区分大小写搜索的工作示例。在C ++ 11中,它将更加冗长:
#include <map>
#include <iostream>
#include <cctype>
#include <algorithm>
#include <string>
bool case_insensitive_eq(const char& lhs, const char& rhs)
{
return std::toupper(lhs) == std::toupper(rhs);
}
bool case_insensitive_string_eq(const std::string& lhs, const std::string& rhs)
{
return std::equal(lhs.begin(),
lhs.end(),
rhs.begin(),
case_insensitive_eq);
}
typedef std::map<std::string, std::string> StringMap;
struct case_insensitive_key_eq
{
case_insensitive_key_eq(const std::string& key) : key_(key) {}
bool operator()(StringMap::value_type item) const
{
return case_insensitive_string_eq(item.first, key_);
}
std::string key_;
};
int main()
{
StringMap my_map;
my_map["Helloooo"] = "foo";
StringMap::iterator it = std::find_if(my_map.begin(),
my_map.end(),
case_insensitive_key_eq("HeLlOOoo"));
if (it != my_map.end())
{
std::cout << "Found element " << it->second << std::endl;
} else
{
std::cout << "element not found\n";
}
}