检查白名单中是否包含一对的功能?

时间:2015-12-31 22:38:58

标签: algorithm

所以说我有一个"白名单对的列表"像这样:

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)
}

有更好的方法吗?

3 个答案:

答案 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将两个值保持一定的顺序,但没有任何意义。例如,(x,y)=&gt; X / Y,和(y,x)=&gt; X / Y。 你只选择ascendent(或descendent):X&lt;是的

解决方案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)。假设你对内存命中没问题,这应该是性能最高的解决方案(在执行时间方面表现不错,不一定是内存开销)。