如何在搜索中不使用std::map的自定义比较函数(map::find)

How not to use custom comparison function of std::map in searching ( map::find)?

本文关键字:map 自定义 比较 函数 find std 搜索      更新时间:2023-10-16

正如您在我的代码中看到的,lenMap是一个带有自定义比较函数的std::map。这个函数只是检查字符串的长度。

现在,当我想搜索某个关键字(使用map::find)时,映射仍然使用自定义比较函数。

但是当我搜索某个关键字时,我如何强制我的地图不使用它?

代码:

struct CompareByLength : public std::binary_function<string, string, bool>
{
    bool operator()(const string& lhs, const string& rhs) const
    {
        return lhs.length() < rhs.length();
    }
};
int main()
{
    typedef map<string, string, CompareByLength> lenMap;
    lenMap mymap;
    mymap["one"] = "one";
    mymap["a"] = "a";
    mymap["foobar"] = "foobar";
    // Now In mymap: [a, one, foobar]
    string target = "b";
    if (mymap.find(target) == mymap.end())
        cout << "Not Found :) !";
    else
        cout << "Found :( !"; // I don't want to reach here because of "a" item !
    return 0;
}

映射本身不提供这样的操作。比较函子的想法是创建一个内部排序,以便更快地查找,因此元素实际上是根据函子排序的。

如果需要以不同的方式搜索元素,可以使用STL算法std::find_if()(具有线性时间复杂性),也可以创建使用另一个比较函子的第二个映射。

在您的特定示例中,由于您似乎只对字符串的长度感兴趣,因此您应该使用长度(类型为std::size_t),而不是字符串本身作为键。

顺便说一下,不需要std::binary_function作为基类。从C++11开始,它甚至被弃用,例如,请参阅此处。

比较函数告诉map如何对元素排序以及如何区分它们。如果它只比较长度,那么具有相同长度的两个不同字符串将在映射中占据相同的位置(其中一个将覆盖另一个)。

要么将字符串存储在不同的数据结构中并对其进行排序,要么尝试这个比较函数:

struct CompareByLength
{
    bool operator()(const string& lhs, const string& rhs) const
    {
        if (lhs.length() < rhs.length())
        {
            return true;
        }
        else if (rhs.length() < lhs.length())
        {
            return false;
        }
        else
        {
            return lhs < rhs;
        }
    }
};

我没有测试它,但我相信这将首先按照字符串的长度排序,然后按照字符串通常进行比较的方式排序。

您也可以使用std::map<std::string::size_type, std::map<std::string, std::string>>,并为第一个映射使用长度,为第二个映射使用字符串值。您可能希望将其封装在一个类中,以使其更易于使用,因为没有防止将其弄乱的保护措施。