【问题标题】:find multiple values in unordered_set using find使用 find 在 unordered_set 中查找多个值
【发布时间】:2013-02-13 16:29:41
【问题描述】:

我想使用指定的 equal_to 函数 int unordered_set 示例代码如下:

struct myEqual
{       //string with one different character is considered equal
    bool operator()(const string &s1, const string &s2)const
    {

        if(s1.length() != s2.length()) return false;
        int dis = 0;
        for(unsigned int i = 0; i<s1.size(); i++)
        {
            if(s1[i] != s2[i])
            {
                dis++;
                if(dis >= 2) return false;
            }               
        }
        return true;
    }
};

int main()
{
    unordered_set<string, std::tr1::hash<string>, myEqual> myDict;
    myDict.insert("a");
    myDict.insert("b");
    myDict.insert("c");

    unordered_set<string, std::tr1::hash<string>, myEqual>::iterator it = myDict.find("k");
    if(it == myDict.end())
    {
        cout<<"myequal not work"<<endl;
    }
    else
    {
        cout<<*it<<endl;
    }
    return 0;
}

根据 myEqual 函数,“a”、“b”、“c”三个值与“k”“相等”,但是 find 只返回一个迭代器。 有没有办法找到所有相等的价值?

【问题讨论】:

    标签: c++ c++11 equals tr1 unordered-set


    【解决方案1】:

    这里有两个问题,都与寻找元素无关:

    1. 由于"a""b""c" 都比较相等,因此您只能将其中一个保留在unordered_set 中。
    2. 您有比较相等但可能具有不同哈希码的元素。这违反了为了使无序集正常工作而必须履行的合同。

    要记住的一个更普遍的问题是您的等价关系不是传递的:"aa" 等于 "ab""ab" 等于 "bb"。然而"aa" 不等于"bb"

    【讨论】:

    • 回复:不同的哈希码:好点。这个容器可能是一场灾难。
    • @PeteBecker 即使使用 std::unordered_multiset 成员 equal_range 也无法用于非传递比较 liveworkspace.org/code/3FAlUx$37
    【解决方案2】:

    最好的方法是解决以下 4 件事

    1. 使用std:unordered_multiset 作为容器

    2. 使用相互一致散列函数和键比较函数。特别是,哈希函数需要将相等的元素映射到相等的键。

    3. 使用等价关系的比较函数。特别是,这意味着如果A==BB==C,那么A==C,其中== 对应于您的myEqual

    4. 使用返回一对迭代器的成员函数equal_range。如果 第一个迭代器不等于容器的结尾,可以循环。

    代码:

    auto res = myDict.equal_range("k");
    if(res.first == myDict.end())
    {
        cout<<"myequal not work"<<endl;
    }
    else
    {
        for (auto it = res.first; it != res.second; ++it) 
            cout<<*it<<endl;
    }
    

    您的哈希函数和比较运算符目前都违反了 C++ 标准库的容器要求。您的哈希码不会将相等(在您的myEqual 意义上)字符串映射到相等的哈希键。您的比较运算符不具有传递性(参见@NPE 的示例)。这意味着您不能使用std::unordered_setstd::unordered_multiset。如果这样做,您的代码会产生未定义的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-25
      相关资源
      最近更新 更多