将集合与集合集合进行比较的最佳算法

时间:2012-09-24 06:30:15

标签: c++ algorithm set subset

在作为特定集的子集的有限集合集中查找集合的最佳算法是什么?

例如,如果

A = {1, 2}
B = {2, 3, 4}
C = {3, 5}
D = {6}

和X = {1, 2, 3, 5}

然后,A和C是X的子集。

我是否可以使用线性时间复杂度进行算法?

实现注意事项:集合的成员通常来自非常有限的范围,因此,使用C ++ bitset实现算法可能是个好主意。不是吗?

编辑:集合中的集合数通常远大于X中的元素数(在示例中)。有没有办法在X中的元素数量方面做这个线性?可能使用哈希或什么?

2 个答案:

答案 0 :(得分:7)

让我们暂时假设64个可能的元素。

然后,如果您将每个元素表示为一个位,则可以使用64位长的整数来表示每个集合,然后:a & ba的{​​{3}}和{ {1}}。
如果(且仅当)ba的子集,则b

当然,如果你需要64位以上,你可以使用bitset。

对于大范围的元素,使用哈希表存储(一次)超集,然后迭代潜在的子集以检查是否所有元素都在其中。
输入大小是线性的(平均情况)。


编辑:(对编辑问题的回复)

除非您预先存储了一些关于数据的信息 - 否则无法完成betetr然后a & b == a其中| X |是集合X的大小,O(|X| + n*min{m,|X|})是集合的数量,n是集合的平均大小。
原因是因为在最坏的情况下,你需要读取所有集合中的所有元素(因为你为每个集合读取的最后一个元素决定它是否是一个子集),因此如果没有,我们就无法实现更好的目标先前对集合的了解。

建议的解决方案是:
比特集:m
哈希解决方案:O(|X|*n)(平均情况)

虽然散列解决方案提供了更好的渐近复杂度,但是对于bitset来说常量要好得多 - 因此对于小O(|X| + min{m,|X|}*n)

而言,bitset解决方案可能会更快

答案 1 :(得分:1)

如果你没有时间建立一些额外的结构,O(log(n))解决方案将存储代表Trie个体集的位序列。

你不必将你的设置(a.k.a. bitstring)与Amit所设想的所有其他设置进行比较。如果你有一个排序的位串集合,那么每次比较显然会将变量的数量减少一半。是的,当然,构建bitset trie的时间类似于O(n * log(n)),但它是一个预处理。