所以说我有一个"白名单对的列表"像这样:
a | b
a | c
f | g
并说我想写一个这样的方法:
function checkIfInWhitelist(itemOne, itemTwo) {
...
}
这是所需的功能:
checkIfInWhiteList(a, b) // true
checkIfInWhitelist(b, a) // true
checkIfInWhitelist(b, c) // false
checkIfInWhiteList(g, f) // true
(基本上我想检查这对是否存在于白名单中)
最好和最有效的方法是什么?
我在想一本词典,其中的键是白名单中出现的任何内容,而值是与键匹配的内容列表?
例如,上面的三个白名单对将映射到:
a: [b, c]
b: [a]
f: [g]
g: [f]
然后,checkIfInWhitelist
将实现如下:
function checkIfInWhitelist(itemOne, itemTwo) {
return map.contains(itemOne) && map[itemOne].contains(itemTwo)
}
有更好的方法吗?
答案 0 :(得分:0)
如果你有一个合理的hash实现,它适用于std::pair
(例如Boost中的那个),并且对象有一个快速的总顺序方法,那么你可以用一个哈希表来做,而不是人为的将桌子的大小加倍。只需使用std::unordered_set
并在插入之前将每对标准化为非递减顺序。 (即,如果< b,插入std :: make_pair(a,b);否则插入std :: make_pair(b,a)。)
非常粗糙的代码,缺少大量的样板。我应该使用完美转发。未经测试。
template<typename T> struct PairHash {
std::unordered_set<std::pair<T, T>> the_hash_;
using iterator = typename std::unordered_set<std::pair<T, T>>::iterator;
std::pair<iterator, bool> insert(const T& a, const T& b) {
return the_hash_.insert(a < b ? std::make_pair(a, b)
: std::make_pair(b, a));
}
bool check(const T& a, const T& b) {
return the_hash_.end() != the_hash_.find(
a < b ? std::make_pair(a, b)
: std::make_pair(b, a));
}
};
答案 1 :(得分:0)
执行此操作的最小方法:
拥有包含数据的哈希映射以及您要检查的内容。
如果您想检查未排序的对,请保留未排序对
的散列图未分类数据的可能解决方案:
解决方案A需要更多空间,更多时间(您必须比较集合)。
解决方案B需要一个小程序(订单 a , b )但其他一切都更快
要进行检查,您必须预先处理:对数据进行排序:( a , b )=&gt; a , b 如果 a &lt; b 或 b , a 如果 b &lt; 一
具有已排序数据的解决方案C
预处理时间较长,但(稍快一点)检查:
在Hashmap中保留每个( a , b )和( b , a ):HashMap列表的例子(或对的一些实现)
所以你的支票是直接的。但是你的第一个预处理需要:O(2n.log 2.n)= 2 O(n.log n)+ 2 log2 O(n)。 所以这取决于你将处理多少支票。
由于比较和反转 a 和 b 非常快,我会推荐解决方案B.
如果您知道数据的类型(例如alpha),您可以将这对夫妇存储在字符串中,例如: a-b
您的解决方案不是最佳解决方案。
它结合了我的解决方案C和A的不良影响:2个嵌入式哈希集合和重复数据。
它忘了c:[a]。
希望它有所帮助。
答案 2 :(得分:-1)
你可能做得比O(1)更好 - 只需使用散列实现,平均给你O(1)查询时间(例如C ++ STL unordered_map)。假设你对内存命中没问题,这应该是性能最高的解决方案(在执行时间方面表现不错,不一定是内存开销)。