动态equal_to函数unordered_map boost

Dynamic equal_to function unordered_map boost

本文关键字:map boost unordered to equal 动态 函数      更新时间:2023-10-16

我有一个无序的映射字符串到int,它使用自定义的equal_to函数定义为:

bool hashEqual::operator ()(const string &a, const string &b) const
{
    if (a.size() != b.size())
        return false;
    return std::inner_product(
        a.begin(), a.end(), b.begin(),
        0, std::plus<unsigned int>(),
        std::not2(std::equal_to<std::string::value_type>())
        ) <= 8;  
}           

基本上它的作用是,如果两个键的汉明距离等于或小于8,则它们是相同的键。

问题是我希望距离阈值是动态的,以便让用户通过命令行设置它。用变量阈值或类似的东西代替8。

我不是在寻找像全局变量这样的hack(除非它是实现这一目标的唯一方法),而是为了"好方法"。

为什么' unordered_map '工作不可靠

一个好的通用哈希函数以一种可重复但看似随机的方式将键映射到桶,我的意思是,如果键变化了一个位,那么桶应该是统计无关的——就好像你随机选择了另一个。那么,假设你有一个包含一些现有元素的哈希表:

[ bucket 0 - "abcde fghij" ]
[ bucket 1 - <empty> ]
[ bucket 2 - <empty> ]
[ bucket 3 - "01234 56789", "77777 QQQQQ" ]  (2 colliding values for this bucket)
[ bucket 4 - "XXXXX YYYYY" ]
[ bucket 5 - <empty> ]

如果你想插入"Abcde fghij",那么你可以哈希到这些桶中的任何一个-你应该没有更多的机会是桶0,但如果桶是而不是桶0,那么你将甚至永远不会尝试与"abcde fghij"进行ham-距离感知的相等比较。


为什么' multimap '不能可靠地工作

假设我们有一个multimap,其中有一些现有的字符串(S1到S6按字典顺序递增-每个元素与其他元素的汉明距离大于8),实际的平衡二叉树可能看起来像:

            S4
          /    
        S2       S6
       /       /  
      S1   S3  S5

现在,假设S1恰好是"Abcde fghij", S4是"ZZZZZ ZZZZZ",我们去插入"abcde fghij":

  • 即使有汉明距离比较,"ZZZZZ ZZZZZ" < "abcde fghij"(记住'Z' < 'a'是ASCII顺序)所以multimap期望"abcde fghij"被存储在树的右边…

  • 然后将
  • "abcde fghij"与S6进行比较,如果小于S5,并将相应地插入,但关键的是,永远不会与S1进行比较


这让我回到我之前的评论:

我不认为有任何简单和正确的方法来做比较除了蛮力(尝试每一个组合)。对于相同的数据,如果顺序不同,结果也会不同。

我明白了。

在类hashEqual中完成所有操作。我这样修改了定义:

class hashEqual {
    private:
        int th;
    public:
       hashEqual();
        hashEqual(int th) { this->th = th; }; // This implemetation on the .cpp
        bool operator ()(const string &a, const string &b) const;
};

操作符()实现:

bool hashEqual::operator ()(const string &a, const string &b) const
{
    if (a.size() != b.size())
        return false;
    return std::inner_product(
        a.begin(), a.end(), b.begin(),
        0, std::plus<unsigned int>(),
        std::not2(std::equal_to<std::string::value_type>())
        ) <= this->th;  
}   

在unordered_map的构造函数中:

boost::unordered_map<string, unsigned int, boost::hash<string>, hashEqual> myMap(size, boost::hash<string>(), hashEqual(threshold));