Algorithm 使用后缀树的近似子字符串匹配
本文讨论了近似子串匹配技术,该技术利用a来提高匹配时间。每个答案都针对不同的算法Algorithm 使用后缀树的近似子字符串匹配,algorithm,string-matching,suffix-tree,edit-distance,Algorithm,String Matching,Suffix Tree,Edit Distance,本文讨论了近似子串匹配技术,该技术利用a来提高匹配时间。每个答案都针对不同的算法 近似子字符串匹配尝试在字符串T中查找子字符串(模式)P,最多允许k不匹配 要了解如何创建后缀树,请单击。然而,有些算法需要额外的预处理 我邀请人们添加新的算法(即使是不完整的算法)并改进答案。这是本主题的原始问题 Esko Ukkonen教授发表了一篇论文:后缀树上的近似字符串匹配。他讨论了具有不同匹配时间的3种不同算法: 算法A:O(mq+n) 算法B:O(mq日志(q)+输出大小) 算法C:O(m^2q+输出大
T
中查找子字符串(模式)P
,最多允许k
不匹配我邀请人们添加新的算法(即使是不完整的算法)并改进答案。这是本主题的原始问题 Esko Ukkonen教授发表了一篇论文:后缀树上的近似字符串匹配。他讨论了具有不同匹配时间的3种不同算法:
O(mq+n)
O(mq日志(q)+输出大小)
O(m^2q+输出大小)
m
是子字符串的长度,n
是搜索字符串的长度,q
是编辑距离
我一直在试图理解算法B,但在遵循这些步骤时遇到了困难。有人有过这种算法的经验吗?如能提供示例或伪算法,将不胜感激
特别是:
输出的大小是指什么?最后的输出阶段列出了T
中所有标记为输出的r
状态下出现的键(r)
I
代表什么。它没有初始化,并且似乎没有递增root
表示初始状态g(a,c)=b
其中a
和b
是树中的节点,c
是树中的字符或子字符串。所以这代表了一种转变;从a
,沿着c
表示的边,我们移动到节点b
。这被称为转到过渡。因此,对于下面的后缀树,g(根,'ccb')=红色节点
Key(a)=边序列
,其中a
表示树中的节点。例如,键(红色节点)=“ccb”
。因此g(根,键(红色节点))=红色节点
键(节点的子集)={Key(节点)|节点∈ S}
a
和b
,f(a)=b
:用于所有(或者可能存在)a
≠ root
,存在字符c
、子字符串x
、节点b
,使得g(root,cx)=a
和g(root,x)=b
。我认为,对于上面的后缀树示例,这意味着f(粉色节点)=绿色节点
其中c='a'
和x='bccb'
H
,它包含后缀树中的一个节点和一个值对。该值由loc(w)
给出;我仍然不确定如何评估这个功能。此字典包含尚未消除的节点extract min(H)
是指从H
中获取具有对(节点,loc(w))
中最小值的条目该算法的关键似乎与如何评估
loc(w)
有关。我用组合答案构建了后缀树;然而,这些算法在后缀trie(未压缩后缀树)上工作。因此,像深度这样的概念需要以不同的方式进行维护和处理。在后缀trie中,深度表示后缀长度;在后缀树中,深度仅表示树中的节点深度。您做得很好。我对算法不太熟悉,但今天读了报纸。你所写的一切都是正确的。你是对的,解释的某些部分假设了很多
您的问题
1.根据后缀树或输入字符串,输出的大小是指什么?最后一个输出阶段列出T中所有键(r)的出现情况,以及标记为输出的所有状态r
输出由p在T中的最大k距离匹配组成。特别是,您将获得每个匹配的最终索引和长度。很明显,这也是O(n)(记住大O是一个上界),但可能更小。这是对不可能在少于O(p)的时间内生成p个匹配的事实的认可。其余的时间限制只涉及模式长度和可行前缀的数量,两者都可以任意小,因此输出大小可以占主导地位。考虑k=0,输入是“a”重复n次与模式“a”。
2.查看算法C,定义函数dp(第四页);我不明白我代表的是什么索引。它没有初始化,并且似乎没有递增
你说得对。这是个错误。循环索引应该是i
。那么j
呢?这是与动态程序中正在处理的输入字符相对应的列的索引。它实际上应该是一个输入参数
让我们后退一步。第6页的示例表格使用前面给出的方程式(1-4)从左到右逐列计算。这表明只需要前面的D和L列就可以得到下一列。函数dp
只是从j-1
计算列j
的思想的一个实现。D和L的j
列分别称为D
和L
。列j-1
D和L是D'
Let r = root of (uncompressed) suffix trie
Set r's cached d,l with formulas at end page 7 (0'th dp table columns)
// Invariant: r contains cached d,l
for each character t_j from input text T in sequence
Let s = g(r, t_j) // make the go-to transition from r on t_j
if visited(s)
r = s
while no cached d,l on node r
r = f(r) // traverse suffix edge
end while
else
Use cached d',l' on r to find new columns (d,l) = dp(d',l')
Compute |Q_j| = l[h], h = argmax(i).d[i]<=k as in the paper
r = s
while depth(r) != |Q_j|
mark r visited
r = f(r) // traverse suffix edge
end while
mark r visited
set cached d,l on node r
end if
end for
H = { (0 => root) } // we use (loc => state) for min heap elements
until H is empty
(j => s_j) = H.delete_min // remove the min loc mapping from
(d, l) = dp(d', l', j) where (d',l') are cached at paraent(s_j)
Compute |Q_j| = l[h], h = argmax(i).d[i]<=k as in the paper
r = s_j
while depth(r) > |Q_j|
mark r eliminated
H.delete (_ => r) // loc value doesn't matter
end while
set cached d,l on node r
// Add all the "next states" reachable from r by go-tos
for all s = g(r, a) for some character a
unless s.eliminated?
H.insert (loc(s) => s) // here is where we use the trie to find loc
// Update H elements that might be newly covered
w = f(s) // suffix transition
while w != null
unless w.eliminated?
H.increase_key(loc(w) => w) // using explanation in Lemma 9.
w = f(w) // suffix transition
end unless
end while
end unless
end for
end until