【发布时间】:2013-08-02 12:21:59
【问题描述】:
在一个程序中,我需要有效地回答以下形式的查询:
给定一组字符串
A和一个查询字符串q,返回所有s ∈ A,使得q是subsequence的s
例如,给定A = {"abcdef", "aaaaaa", "ddca"} 和q = "acd",应该返回正好"abcdef"。
以下是我目前考虑过的:
-
对于每个可能的字符,将其出现的所有字符串/位置制作一个排序列表。查询交错涉及的字符列表,并扫描它以查找字符串边界内的匹配项。
这对于单词而不是字符可能更有效,因为不同字符的数量有限会使返回列表非常密集。
-
对于每个可能具有的 n 前缀
q,存储所有匹配字符串的列表。n可能实际上接近 3。对于超过该长度的查询字符串,我们会强制使用初始列表。这可能会加快一些速度,但可以很容易地想象在
A中的所有字符串附近都存在一些 n 子序列,这意味着最坏的情况与仅暴力破解整个集合相同。
您是否知道任何数据结构、算法或预处理技巧可能有助于有效地为大型As 执行上述任务? (我的ss 大约有 100 个字符)
更新: 有人建议使用 LCS 来检查 q 是否是 s 的子序列。我只是想提醒一下,这可以使用一个简单的函数来完成,例如:
def isSub(q,s):
i, j = 0, 0
while i != len(q) and j != len(s):
if q[i] == s[j]:
i += 1
j += 1
else:
j += 1
return i == len(q)
更新 2: 我被要求提供更多关于 q、A 的性质及其元素的详细信息。虽然我更喜欢尽可能通用的东西,但我认为A 的长度约为 10^6,并且需要支持插入。元素 s 将更短,平均长度为 64。查询 q 将只有 1 到 20 个字符并用于实时搜索,因此查询“ab”将在查询“abc”之前发送”。同样,我更希望解决方案尽可能少地使用上述内容。
更新 3: 我突然想到,带有 O(n^{1-epsilon}) 查找的数据结构可以让您解决 OVP / 反驳 SETH 猜想。这大概就是我们受苦的原因。唯一的选择是反驳猜想、使用近似值或利用数据集。我想 quadlets 和尝试会在不同的设置下做最后一个。
【问题讨论】:
-
如果我输入
de,它还会返回abcdef吗? -
是的,我已经添加了一个指向 Wikipedia 的链接,用于精确定义子序列
-
q或q和s之间的关系是否还有其他特点?比如q很可能包含s的相邻字符,s的长度与q的顺序相同,等等。如果是这种情况,你可以看看algorithm for BLAST。如果不是,我认为A的预处理不会有用,因为s的任何子字符串都与q无关。 -
@lcn Blast 好像是找到目标数据库中与查询的编辑距离最短的子串,所以经常会给出错误的答案
-
@ThomasAhle,如果您的
q包含s的一些子字符串,我建议的是BLAST 使用的预处理想法。 BLAST 的目标并不重要。
标签: string algorithm search data-structures language-agnostic