【问题标题】:C++ unordered_set hash function fail if using user defined struct如果使用用户定义的结构,C++ unordered_set 哈希函数会失败
【发布时间】:2020-12-09 21:26:16
【问题描述】:

我有一个关于 C++ unordered_set 哈希函数的问题让我大吃一惊。这是代码。

typedef struct chess{
    vector<pair<int,int>> *b_chess;              // pointer to boxes coordinates

    bool operator==(const  chess& b) const{
        if (b_chess->size() != b.b_chess->size()) {
            return false;
        }
        for(int i = 0; i<b_chess->size();i++){
            if( (*b_chess)[i] != (*b.b_chess)[i] ) {
                return false;
            }
        }

        return true;
    }
} chess;

struct chess_hash{
    size_t operator()(const chess &b) const{
        size_t x_value, y_value,hash_value ;
        for(ll i = 0; i< b.b_chess->size();i++){
            x_value += (*b.b_chess)[i].first * i;
            y_value += (*b.b_chess)[i].second * i;
        }
        hash<size_t> hash_ll;
        hash_value = size_t(x_value+y_value);
        return hash_value;
    }
};

int main(){
    vector<pair<int,int>> v = {{1,2},{3,4},{5,6}};
    vector<pair<int,int>> *v1 = new vector<pair<int,int>> (v);
    vector<pair<int,int>> *v2 = new vector<pair<int,int>> (*v1);
    chess c1;
    chess c2;
    c1.b_chess = v1;
    c2.b_chess = v2;
    unordered_set<chess, chess_hash> s1;
    unordered_set<chess, chess_hash>::hasher fn = s1.hash_function();
    cout << "c1's hashvalue " << fn(c1) <<" c2's hashvalue "<< fn(c2) << endl;     //  two hashvalues are different
    if( c1 == c2) cout <<"SAME data\n";      // This line will print same data

    s1.insert(c1);
    if(s1.count(c1)){
        cout <<"Found chess\n";               // it won't go there
    }
}

在主函数中,我有一个对向量(框的坐标),我有两个用户定义的结构国际象棋指向它们的相应数据。

程序结果为:

c1的哈希值6422192 c2的哈希值1878014541

相同的数据

另一种情况:

如果我定义一个函数 go_hash(const chess &b)


    size_t go_hash(const chess &b) const{
        size_t x_value, y_value,hash_value ;
        for(size_t i = 0; i< b.b_chess->size();i++){
            x_value += (*b.b_chess)[i].first * i;
            y_value += (*b.b_chess)[i].second * i;
        }
        hash<size_t> hash_ll;
        hash_value = hash_ll(x_value+y_value);
        return hash_value;
    }

go_hash(c1) 将返回与 go_hash(c2) 相同的哈希值

我不明白为什么两段代码会产生不同的结果。是否还有其他 unordered_set 作为 STL 正在做的我错过的事情?我提供了一个散列函数和一个 operator== 重载函数。任何帮助将不胜感激!提前致谢!

【问题讨论】:

    标签: c++ c++11 struct hashset


    【解决方案1】:

    问题似乎是您没有在chess_hash::operator()/go_hash 中初始化变量x_valuey_value;请注意,C++ 不会 0 初始化像这样的整数变量。 这会使您的哈希函数返回不确定的值,即使在相同的输入数据上也会给您不同的结果。

    我建议打开编译器警告 (-Wall),这样的错误通常会被编译器捕获。

    【讨论】:

    • 非常感谢!我认为有一些 stl 正在实施,我错过了大声笑。顺便说一句,刚刚测试,添加 -Wall 标志并没有发现这个错误。
    • g++ 没有,真可惜。但幸运的是叮当声。
    猜你喜欢
    • 2018-06-07
    • 1970-01-01
    • 2019-06-13
    • 2013-12-11
    • 1970-01-01
    • 2012-11-09
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    相关资源
    最近更新 更多