如何使 map::find 操作不区分大小写?

新手上路,请多包涵

map::find 方法是否支持不区分大小写的搜索?我有一张地图如下:

 map<string, vector<string> > directory;

并希望以下搜索忽略大小写:

 directory.find(search_string);

原文由 TL36 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.3k
2 个回答

默认情况下它不会。您必须提供一个自定义比较器作为第三个参数。以下片段将帮助您…

   /************************************************************************/
  /* Comparator for case-insensitive comparison in STL assos. containers  */
  /************************************************************************/
  struct ci_less : std::binary_function<std::string, std::string, bool>
  {
    // case-independent (ci) compare_less binary function
    struct nocase_compare : public std::binary_function<unsigned char,unsigned char,bool>
    {
      bool operator() (const unsigned char& c1, const unsigned char& c2) const {
          return tolower (c1) < tolower (c2);
      }
    };
    bool operator() (const std::string & s1, const std::string & s2) const {
      return std::lexicographical_compare
        (s1.begin (), s1.end (),   // source range
        s2.begin (), s2.end (),   // dest range
        nocase_compare ());  // comparison
    }
  };

std::map< std::string, std::vector<std::string>, ci_less > myMap; 一样使用它

注意:std::lexicographical_compare 有一些细节。如果您考虑语言环境,字符串比较并不总是那么简单。如果有兴趣,请参阅 clc++ 上的 线程。

更新:使用 C++11 std::binary_function 已被弃用并且是不必要的,因为类型是自动推断的。

   struct ci_less
  {
    // case-independent (ci) compare_less binary function
    struct nocase_compare
    {
      bool operator() (const unsigned char& c1, const unsigned char& c2) const {
          return tolower (c1) < tolower (c2);
      }
    };
    bool operator() (const std::string & s1, const std::string & s2) const {
      return std::lexicographical_compare
        (s1.begin (), s1.end (),   // source range
        s2.begin (), s2.end (),   // dest range
        nocase_compare ());  // comparison
    }
  };

原文由 Abhay 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是与 strcasecmp(仅适用于 posix)不同的跨平台标准 c++ 解决方案,不使用我亲自编写的任何外部库,如 boost。它利用了 std::map 的比较功能。

 #include <algorithm>
#include <cctype>
#include <iostream>
#include <map>
#include <string>

bool caseInsensitiveCompare(const std::string& a, const std::string& b) {
  std::string aLower = a;
  std::string bLower = b;
  std::transform(aLower.begin(), aLower.end(), aLower.begin(), [](unsigned char c){ return std::tolower(c); });
  std::transform(bLower.begin(), bLower.end(), bLower.begin(), [](unsigned char c){ return std::tolower(c); });
  return aLower < bLower;
};

int main()
{
  std::map<std::string, std::string, decltype(&caseInsensitiveCompare)> myMap(&caseInsensitiveCompare);
  myMap.insert({"foo", "foo"});
  myMap.insert({"bar", "bar"});
  myMap.insert({"baz", "baz"});

  auto it = myMap.find("FoO");
  if (it != myMap.end()) std::cout << "Found FoO: " << it->second << std::endl;
  else std::cout << "Not found FoO" << std::endl;

  it = myMap.find("foo");
  if (it != myMap.end()) std::cout << "Found foo: " << it->second << std::endl;
  else std::cout << "Not found foo" << std::endl;

  it = myMap.find("not contained");
  if (it != myMap.end()) std::cout << "Found not contained: " << it->second << std::endl;
  else std::cout << "Not found notcontained" << std::endl;

  return 0;
}

原文由 László Papp 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题