我需要通过不区分大小写的比较从 vector 列表中找到字符串。有没有不使用 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
?
最佳答案
std::map::find
依赖于 map 的内部排序。如果要使用此方法进行搜索,则需要使用不区分大小写的比较功能构建 map ,也就是说,不区分大小写的 WRT 键的 map 。
这可以通过利用 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;
如果您希望您的 map 具有标准的、区分大小写的行为,但又想执行不区分大小写的搜索,那么您需要使用 std::find_if
用一个合适的谓词。但是在这里你失去了 map 的 O(logN) 查找的优势。
这是在标准 map 中进行不区分大小写搜索的工作示例。在 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";
}
}
关于c++ - 使用 std::find 在 std::map 中进行不区分大小写的搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23153967/