C++ 比较集合与集合的最佳算法

C++ 比较集合与集合的最佳算法,c++,algorithm,set,subset,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中元素的数量来线性化呢?可能使用哈希或其他什么?让我们先假

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

例如,如果

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

那么,A和C是X的子集

有没有一种算法可以在线性时间复杂度下实现这一点

<强>执行注释:集合的成员一般都在非常有限的范围内,因此,使用C++ BITSET实现算法是一个好主意。不能吗


编辑:集合中的集合数通常大于X中的元素数(在示例中)。有没有一种方法可以根据X中元素的数量来线性化呢?可能使用哈希或其他什么?

让我们先假设64个可能的元素

然后,如果将每个元素表示为位,则可以使用64位长的整数表示每个集合,然后:
a&b
a
b
的组合。
如果(且仅当)
a
b
的子集,则
a&b==a

当然,如果需要64位以上的数据,可以使用位集

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


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

除非在数据上预先存储了一些信息,否则在
O(|X |+n*min{m,|X |})
中,|X |是集合X的大小,
n
是集合的数量,
m
是集合的平均大小之前,就无法完成。
这样做的原因是因为在最坏的情况下,您需要读取所有集合中的所有元素(因为您为每个集合读取的最后一个元素决定它是否是子集),因此如果没有集合的先前知识,我们无法获得更好的结果

建议的解决办法是:
位集:
O(| X |*n)

散列解决方案:
O(|X |+min{m,|X |}*n)
(平均情况)


尽管散列解决方案提供了更好的渐进复杂性,但常数对于位集来说要好得多,因此对于较小的
|X |

来说,位集解决方案可能会更快,如果不限制构建一些额外结构的时间,那么O(log(n))解决方案是将代表单个集合的位序列存储在一个集合中


您不必像Amit假设的那样将您的集合(也称为位字符串)与所有其他集合进行比较。如果您有一个排序的位字符串集合,那么每次比较都会明显地将变体的数量减少一半。是的,当然,构建位集trie的时间类似于O(n*log(n)),但这是一个预处理过程。

在真正的线性时间中无法做到这一点。测试一个集合是否包含另一个集合在技术上永远是二次时间,但使用哈希表将使这样的问题在实践中成为线性时间(如果集合的长度合理)。因此,你的问题的答案是,时间复杂度将是
M*N*Q
,如果M是集合的数量(A-D),N是这些集合中最大的集合的大小,Q是集合X的大小。你能给我一个链接或可能是算法的名称吗?与其说算法重要,还不如说算法的数据结构重要。正如您(和@amit)所提到的,如果可能的元素数量有限,则位集非常有用。A是另一种非常有用的数据结构(C++中,它被称为AN。你的答案是正确的。但是如果集合中的集合数量非常大,但X中的元素数量很少?我能更有效地这样做吗?”穆罕默德:答案是:如何排序的位串集合可以减少比较的数量?例如,如果x= {3,6}。3在其中一个集合中,6可能在另一个集合中没有3?我们如何将集合放入Trie?如果我们想在Trie中搜索集合,时间复杂度很好。但是我们必须计算X和Trie中每个项目之间的交集。Trie如何帮助我们找到集合的交集?