我阅读了一些关于确定集A
是否是另一集B
的子集的帖子。但我发现很难确定使用什么算法。以下是问题的概述:
A
数组,我在程序开始时收到它。关于结构知之甚少。阵列中的每个字符串可以任意长,并且条目的数量不受限制。虽然通常可以假设数组中的条目数不会过大(<100)。n
的对象列表。n
对象也会有一个字符串数组B
,即会有n
B
个数组。一旦程序运行,B
将被修复,即它们在运行时不会改变。A
是B
的子集,我想确定每个对象。现在,我想到了哈希表。但是,在我看来,如果只有一个B
和很多A
s,它们才会有效。然后我可以为B
创建一个哈希表,并根据我的哈希表检查每个对象的每个字符串数组。但事实并非如此,因为只有一个A
但n
B
s。这样做的有效算法是什么?
示例:
A: ["A", "G", "T"]
B1: ["C", "G"]
B2: ["K", "A", "U", "T", "G"]
.
.
.
Bn: ["T", "I", "G", "O", "L"]
此处A
是B2
的子集,但不是B1
的子集,而不是Bn
。
答案 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>
为了便于检查,您可能需要按字母顺序排序每一组。这样就可以通过两组字符串检查A
对(线性)扫描中的单个B
。
对于小A
和大B
集,使用二分搜索而不是线性扫描在B
中查找字符串可能更有效;这也需要预先排序B
。