我觉得可能有一个算法,但我只是不知道它叫什么。
假设你有一个“大”的单词,
('apple', 'orange', 'potato', 'tomato', 'river', 'mountain', 'forest')
以及将被视为要求的较小集合列表:
[('apple'),
('potato', 'tomato'),
('cockroach', 'dynamite')]
有没有办法散列/预先计算较小的集合列表,以便您可以分辨出哪些必需的单词集合而不必逐个进行处理?
在这个例子中,函数会告诉你满足前两个要求('apple')和''potato','tomato')。
答案 0 :(得分:0)
我不认为需求方面的任何预处理都会有所帮助。
但是,在更大的设置方面,您可以预先排序,以便在检查约束时允许您执行二进制搜索。
如果您在大型集合中有n
个元素,并且需求中包含k
个元素,那么通过扫描整个大集合,您需要花费O(kn)
时间进行天真搜索。但是,使用二进制搜索会花费O(klog(n))
时间。两者之间的差异在实践中是巨大的。
答案 1 :(得分:0)
对大型列表和所有小型列表进行排序。这意味着您可以通过迭代大型列表来匹配较小的列表,并检查每个较小列表中的第一个不匹配元素,因为较小列表中的字符串将按顺序匹配。
为了有效地创建一个哈希集来检查大型集中是否存在字符串,以及从字符串键映射到该字符串是第一个不匹配元素的所有字符串列表的集合的哈希。您的伪代码算法是:
for each string S in large list:
set of lists SOL = hashmap[S]
for each list L in SOL:
remove L from SOL and remove SOL from hashmap if now empty
find next string S2 in L after S
if S2 doesn't exist (i.e. S was the last unmatched string in the small list)
L is a match, add to your list of matches
else if S2 is in largelisthashset
set of lists SOL2 = hashmap[S2], create if doesn't exist
add L to SOL2
hashmap[S2] = SOL2
您可以在每个小列表中保持指向当前位置的指针,这样“在S之后的L中找到下一个字符串S2”步骤为O(1)。所以你有一个带有字符串列表和索引的对象,然后你就会在每个字符串的哈希中存储一组这些对象。这些集合不需要排序。
初始排序应为O(n log(n)),O(n * m)为查找匹配的字符串列表,假设哈希查找为O(1),m为包含的小数列表的平均数较大列表中的每个字符串(实际上较少,因为如果列表中的所有先前字符串都匹配,则只会匹配较小列表中的字符串。)
与check-each-list方法相比,此算法可节省时间,因为从不处理较大列表中不包含项目的较小列表。如果大型列表更大并且只有少量较小的列表,那么速度较慢,因为使用大型列表中的项目散列检查每个较小的列表可以避免处理大型列表中不包含任何内容的项目较小的清单。但是,你可以通过维护一个在hashmap中有一组列表的字符串的排序列表来加速它,并使用大型列表hashset(或大型列表中的索引的字符串散列)来跳过大型列表中的字符串。你的外部循环在hashmap中没有任何条目。
所以它真的取决于你的名单的相对长度,重叠和数量。