[英]Searching algorithm
我正在寻找一种有效的搜索算法来获取 最长 集合中最短的重复模式(〜2k整数),其中我的集合仅由该重复模式组成(重复模式之间没有噪音),但是最后一次出现模式可能不完整。
示例:我有:[2,4,1,2,4,1,2,4,1,2,4,1,2,4,1]
我想收到: [2,4,1]
我有:[21,1,15,22,21,1,15,22,21,1,15,22,21,1,15]
我想收到: [21,1,15,22]
我有:[3,2,3,2,5]
我想收到: []
(没有模式)
(添加空格只是为了提高可读性)
非常简单的算法如下所示(在Python中,但转换为Javascript应该没有问题):
def check(a, width):
'''check if there is a repeated pattern of length |width|'''
for j in range(width, len(a)):
if a[j] != a[j-width]:
return False
return True
def repeated(a):
'''find the shortest repeated pattern'''
for width in range(1, len(a)):
if check(a, width):
return a[:width]
return []
这也应该是相当有效的,因为在大多数情况下, check()
的循环将在第一次迭代中立即返回,因此您基本上只对列表进行一次迭代。
尝试通过从一开始就向组中添加一个数字开始建立初始分组,直到获得与该组中第一个相同的数字(前一个数字会终止该模式)。 使用它作为测试模式,并进行匹配,直到失败为止。 如果您匹配整个集合(使用特殊的结束模式处理),那么这是一个候选对象。 返回找到初始匹配项的位置,然后继续建立组,直到找到与模式中第一个匹配的另一个数字。 重复一遍,每当找到更长的候选人时就替换候选人。 当您的模式与收集停止的长度相同时(此模式不匹配)。 如果您有候选人,那将是最长的模式。
我认为您可以通过考虑模式周期来解决此问题。 序列A []的周期是最小的整数T,因此对于所有i而言,A [i + T] = A [i]。 在您的情况下,找到周期T即可完成,因为A [0..T-1]是您要寻找的最短模式。 因此,从较小的可能周期T = 1开始,然后测试序列是否满足周期性。 如果是,那么您就完成了(实际上仅在所有元素都相同时才会发生)。 对于任何更大的T,您需要测试对于i = 0..A.len-T-1,A [i + T] = A [i]。 这只是一个简单的循环。
您可以通过观察集合的长度必须是模式长度的倍数来优化搜索。 如果您的集合的大小为素数,则唯一可能的图案长度为1,即所有元素必须相同!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.