我有一个无序的映射字符串到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,变量阈值或类似的东西。
我不是在寻找像全局变量那样的黑客(除非它是实现这一目标的唯一方法),而是为了“好的方式”#34;。
答案 0 :(得分:1)
一个好的通用哈希函数以可重复但以其他方式看似随机的方式将密钥映射到存储桶,我的意思是如果密钥变化甚至只有一个位,那么存储桶应该在统计上不相关 - 就像你&#39 ; d随意挑选另一个。所以,假设您有一个包含一些现有元素的哈希表:
[ 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然后您 甚至不会尝试 与汉堡距离感知的平等比较&#34; abcde fghij&#34;。
想象一下,我们multimap
有一些现有的字符串(S1到S6增加了字典排序顺序 - 每个字符串的汉明距离超过8),实际的平衡二叉树可能看起来像什么模糊地说:
S4
/ \
S2 S6
/ \ / \
S1 S3 S5
现在,让我们说S1恰好是"Abcde fghij"
,S4是"ZZZZZ ZZZZZ"
我们去插入"abcde fghij"
:
即使使用汉明距离比较"ZZZZZ ZZZZZ" < "abcde fghij"
(请记住ASCII顺序为'Z' < 'a'
),因此multimap
期望"abcde fghij"
存储在右侧树的......
"abcde fghij"
与S6进行比较,如果少于S5,则相应插入,但至关重要的是 从未与S1进行任何比较 强>
这让我回到我之前的评论:
我认为除了蛮力之外,还有任何简单而正确的方法可以进行比较(尝试每种组合)。并且结果因另一个订单中的相同数据而异。
答案 1 :(得分:0)
我明白了。
所有操作都在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;
};
operator()实现:
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));