针对一系列集合检查子集的高效算法

时间:2016-01-18 11:01:25

标签: algorithm set subset

我阅读了一些关于确定集A是否是另一集B的子集的帖子。但我发现很难确定使用什么算法。以下是问题的概述:

  • 我有一个字符串A数组,我在程序开始时收到它。关于结构知之甚少。阵列中的每个字符串可以任意长,并且条目的数量不受限制。虽然通常可以假设数组中的条目数不会过大(<100)。
  • 然后我遍历一个长度为n的对象列表。
  • 每个n对象也会有一个字符串数组B,即会有n B个数组。一旦程序运行,B将被修复,即它们在运行时不会改变。
  • 如果AB的子集,我想确定每个对象。

现在,我想到了哈希表。但是,在我看来,如果只有一个B和很多A s,它们才会有效。然后我可以为B创建一个哈希表,并根据我的哈希表检查每个对象的每个字符串数组。但事实并非如此,因为只有一个An B s。这样做的有效算法是什么?

示例:

A:  ["A", "G", "T"]
B1: ["C", "G"]
B2: ["K", "A", "U", "T", "G"]
.
.
.
Bn: ["T", "I", "G", "O", "L"]

此处AB2的子集,但不是B1的子集,而不是Bn

3 个答案:

答案 0 :(得分:2)

一种有效的方法是将集合A表示为特里。这允许检查给定字符串是否属于字符串长度中的线性时间线。

然后没有更好的方法然后详细检查所有Bi和Bi中的所有字符串(如果它属于A)。一旦A中的所有字符串都匹配(在找到字符串时标记字符串),搜索就会停止。

运行时间将与所有B中所有字符串中的字符总数成比例。实际上,将跳过很大一部分字符,如

  • 搜索不在A中的字符串可以提前终止,

  • 即使Bi中还有字符串,子集测试也能得出肯定的结论,

  • 当A中不匹配的字符串比Bi中剩余的字符串多时,子集测试可以得出消极结论。

这种方法肯定是最差的,因为你最多只读一次字符并且每个字符执行一定数量的操作。

答案 1 :(得分:1)

如您事先知道A,您可以设计a collision-free hash function来散列A的所有元素。

然后仅在搜索步骤中对哈希进行操作,而不是字符串。对于B的每个元素,计算其哈希值,然后使用它来查找A的元素。如果找到一个元素,则表示哈希值匹配;那么你还需要比较字符串,以检测它是真正的正面还是偶然的匹配。

计算比赛次数。当该数字等于A的大小时,停止并返回正数结果。如果已经处理了B的所有元素并且匹配数小于A

的大小

答案 2 :(得分:1)

作为第一种方法,我会预先计算集合的一些一般属性,(希望)可以让你快速过滤一些B。这些可能是,例如:

  • 许多字符串 - A如果包含的元素多于B,则肯定不能成为B的子集;
  • 最长字符串的长度 - A肯定不是B的子集,如果A中的最长字符串长于B中的最长字符串; < / LI>
  • 一串字符串&#39;长度。

为了便于检查,您可能需要按字母顺序排序每一组。这样就可以通过两组字符串检查A对(线性)扫描中的单个B

对于小A和大B集,使用二分搜索而不是线性扫描在B中查找字符串可能更有效;这也需要预先排序B