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

时间:2015-12-06 20:14:34

标签: c++ stdmap

正如您在我的代码中所看到的,lenMapstd::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;
}

2 个答案:

答案 0 :(得分:1)

地图本身不提供此类操作。比较仿函数的想法是创建一个内部排序以加快查找速度,因此元素实际上是根据您的仿函数排序的。

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

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

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

答案 1 :(得分:0)

比较函数告诉地图如何订购元素以及如何区分它们。如果仅比较长度,则两个长度相同的不同字符串将占据地图中的相同位置(一个将覆盖另一个)。

将字符串存储在不同的数据结构中并对其进行排序,或者尝试使用此比较函数:

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>>并使用第一个地图的长度和第二个地图的字符串值。你可能想把它包装在一个类中,以便更容易使用,因为没有防止它搞乱的保护。