如何使 map::find 操作不区分大小写?
map::find
方法是否支持不区分大小写的搜索?我有一张地图如下:
map<string, vector<string> > directory;
并希望以下搜索忽略大小写:
directory.find(search_string);
Does the map::find
method support case insensitive search? I have a map as follows:
map<string, vector<string> > directory;
and want the below search to ignore case:
directory.find(search_string);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
默认情况下不会。您必须提供自定义比较器作为第三个参数。以下代码片段将帮助您...
像
std::map
使用它std::string、std::vector、ci_less > myMap;
注意:std::lexicographyal_compare 有一些具体细节。如果考虑区域设置,字符串比较并不总是那么简单。如果有兴趣,请参阅 clc++ 上的此主题。
更新:对于 C++11,
std::binary_function
已弃用,并且没有必要,因为类型是自动推导的。It does not by default. You will have to provide a custom comparator as a third argument. Following snippet will help you...
Use it like
std::map< std::string, std::vector<std::string>, ci_less > myMap;
NOTE: std::lexicographical_compare has some nitty-gritty details. String comparison isn't always straightforward if you consider locales. See this thread on c.l.c++ if interested.
UPDATE: With C++11
std::binary_function
is deprecated and is unnecessary as the types are deduced automatically.这里有一些其他的替代方案,其中包括一种执行速度明显更快的方案。
Here are some other alternatives, including one which performs significantly faster.
对于 C++11 及更高版本:
For C++11 and beyond:
您可以使用三个参数实例化
std::map
:键类型、值类型和比较函数——严格的您喜欢的弱排序(本质上,函数或函子在传递性和反自反性方面表现得像operator<
)。只需定义第三个参数来执行“不区分大小写的小于”(例如,通过比较的小写字符串上的<
),您将获得所需的“不区分大小写的映射”!You can instantiate
std::map
with three parameters: type of keys, type of values, and comparison function -- a strict weak ordering (essentially, a function or functor behaving likeoperator<
in terms of transitivity and anti-reflexivity) of your liking. Just define the third parameter to do "case-insensitive less-than" (e.g. by a<
on the lowercased strings it's comparing) and you'll have the "case-insensitive map" you desire!我使用以下内容:
I use the following:
如果您不想接触地图类型(以保持其原始的简单性和效率),但不介意使用较慢的不区分大小写的查找函数(O(N)):
PS:也许这是 Roger Pate 的想法,但不确定,因为一些细节有点偏离(std::search?,直接字符串比较器?)
In case you don't want to touch the map type (to keep it's original simplicity and efficiency), but don't mind using a slower case-insensitive find function (O(N)):
PS: Maybe it was Roger Pate's idea, but not sure, since some details were a bit off (std::search?, direct string comparator?)
不,您不能使用
find
来做到这一点,因为在这种情况下会有多个匹配项。例如,插入时可以让您执行诸如map["A"] = 1
和map["a"] = 2
之类的操作,现在如果您想要不区分大小写map.find("a")
预期返回值是多少?解决此问题的最简单方法是将字符串仅以一种情况(大写或小写)插入到映射中,然后在查找时使用相同的情况。No, you can not do that using
find
as in that case there will be multiple matches. For example, while inserting lets you have done something likemap["A"] = 1
andmap["a"] = 2
and now if you want a case insensitivemap.find("a")
what is the expected return value? The simplest way to solve this would be insert the string into map in only one case (either upper or lower case) and then using the same case while doing the find.我想提出一个不使用 Boost 或模板的简短解决方案。自 C++11 起,您还可以提供 lambda 表达式 作为地图的自定义比较器。对于 POSIX 兼容系统,解决方案可能如下所示:
Ideone 上的代码
对于 Window,
strcasecmp()
不存在,但您可以使用_stricmp()
改为:注意:根据您的系统以及是否必须支持 Unicode,您可能需要以不同的方式比较字符串。 此问答提供了一个良好的开端。
I'd like to present a short solution without using Boost or templates. Since C++11 you can also provide a lambda expression as custom comparator to your map. For a POSIX-compatible system, the solution could look as follows:
Code on Ideone
For Window,
strcasecmp()
does not exist, but you can use_stricmp()
instead:Note: Depending on your system and whether you have to support Unicode or not, you might need to compare strings in a different way. This Q&A gives a good start.
映射模板的 Compare 元素默认为二进制比较类“less”。看一下实现:
http://www.cplusplus.com/reference/std/ function/less/
您可以创建自己的派生自binary_function(less的父类)的类,并在不区分大小写的情况下进行相同的比较。
The Compare element of the map template defaults to a binary comparison class "less". Look at the implementation:
http://www.cplusplus.com/reference/std/functional/less/
You can likely create your own class that derives from binary_function (the parent class to less) and do the same comparison without case sensitivity.
测试:
Tested:
实现 std::less 函数并通过将两者更改为相同的大小写进行比较。
Implement std::less function and compare by changing both to same case.
这是跨平台的标准 C++ 解决方案,与 strcasecmp(仅适用于 posix)不同,没有使用我亲自编写的任何外部库(如 boost)。它利用了
std::map
的比较功能。This is the cross-platform standard c++ solution unlike strcasecmp (which is only available for posix), without using any external libraries like boost, that I have personally written. It takes advantage of the comparison function of
std::map
.