我发布了这个问题: Non overlapping pattern matching with gap constraint in python;两个月前。我只收到一个回复。但是解决方案很长,并且对于模式中的每个单词,形成一个嵌套循环。有没有办法递归形成以下函数?
i=0
while i < len(pt_dic[pt_split[0]]):
match=False
ii = pt_dic[pt_split[0]][i]
#print "ii=" + str(ii)
# Start loop at next index after ii
j = next(x[0] for x in enumerate(pt_dic[pt_split[1]]) if x[1] > ii)
while j < len(pt_dic[pt_split[1]]) and not match:
jj = pt_dic[pt_split[1]][j]
#print "jj=" + str(jj)
if jj > ii and jj <= ii + 2:
# Start loop at next index after ii
k = next(x[0] for x in enumerate(pt_dic[pt_split[2]]) if x[1] > jj)
while k < len(pt_dic[pt_split[2]]) and not match:
kk = pt_dic[pt_split[2]][k]
#print "kk=" + str(kk)
if kk > jj and kk <= jj + 2:
# Start loop at next index after kk
l = next(x[0] for x in enumerate(pt_dic[pt_split[3]]) if x[1] > kk)
while l < len(pt_dic[pt_split[2]]) and not match:
ll = pt_dic[pt_split[3]][l]
#print "ll=" + str(ll)
if ll > kk and ll <= kk + 2:
print "Match: (" + str(ii) + "," + str(jj) + "," + str(kk) + "," + str(ll) + ")"
# Now that we've found a match, skip indices within that match.
i = next(x[0] for x in enumerate(pt_dic[pt_split[0]]) if x[1] > ll)
i -= 1
match=True
l += 1
k += 1
j += 1
i += 1
修改:对于那些无法获取背景信息的人
我想找到完全没有。出现在序列中的模式的非重叠匹配与间隙约束2。
EG。 A B C
是使用某种算法找到的模式。我必须找到这个模式的总数#出现在A A B B C D E A B C …
这样的序列中,其中最大间隙约束为2。
最大。在序列中没有看到间隙,但是在属于序列中子串的模式的两个单词之间可以看到间隙。例如。 Pat: A B C
和seq: A B D E C B A B A B C D E
。
在这种情况下,A B D E C ...
是匹配,因为A,B和B,C之间允许的最大两个间隙。接下来我们发现A B A B C
为另一个匹配。有趣的是。有两个匹配,(2个字符b / w A,B和2个字符b / w B,C)。但是,我们只将其视为一个,因为它是重叠匹配。 A B X X X C
无效。
答案 0 :(得分:0)
我只是简单地阅读了原始问题。我不确定我是否有差距计算部分。我认为你有L个排序的唯一索引序列,代码搜索所有带L个元素的列表,其中第N个元素来自第N个序列,其中两个相邻的项满足条件prev < next < prev + GAP + 1
无论如何,这个问题是关于嵌套循环的。
以下代码的基本思想是将序列列表传递给递归函数。该函数从中获取第一个序列并迭代它。其余的序列被传递给同一函数的其他实例,其中每个实例都是相同的,即迭代第一个序列并传递其余的序列,直到没有剩下的序列为止。
在此过程中,逐步构建部分解决方案。仅当此部分解满足条件时,递归才会继续。当所有序列都耗尽时,部分解决方案将成为最终解决方案。
list_of_seqs= [
[0, 1, 7, 11, 22, 29],
[2, 3, 8, 14, 25, 33],
[4, 9, 15, 16, 27, 34],
]
def found_match(m):
print(m)
GAP = 2
def recloop(part, ls):
if not ls:
found_match(part)
return
seq, *ls = ls # this is Python3 syntax
last = part[-1] if part else None
# this is not optimized:
for i in seq:
if last is None or last < i <= last + GAP + 1:
recloop(part + [i], ls)
recloop([], list_of_seqs)
对于Python2,用seq, ls = ls[0], ls[1:]