我正在使用列表列表,这些列表中的每一个都有非完美平方根的连续分数周期。
我尝试用它们来检查每个列表中最大重复模式的大小。
有些列表例如:
[
[1,1,1,1,1,1....],
[4,1,4,1,4,1....],
[1,2,10,1,2,10....],
[1,1,1,1,1,4,1,4,1,20,9,8,1,1,1,1,1,4,1,4,1,20,9,8....],
[2,2,2,4,2,2,2,4....],
[1,1,1,13,21,45,3,3,1,16,4,1,4,1,1,1,24,15,1,1,1,13,21,45,3,3,1,16,4,1,4,1,1,1,24,15....],
[1,1,1,3,28,1,1,1,3,28,67,25,1,1,1,3,28,1,1,1,3,28,67,25....]
]
我一直在使用的两种类似方法是:
def lengths(seq):
for i in range(len(seq),1,-1):
if seq[0:i] == seq[i:i*2]:
return i
def lengths(seq):
for i in range(1,len(seq)-1):
if seq[0:i] == seq[i:i*2]:
return i
这两个都采用列表的大小,并从当前位置比较它的索引大小。 问题是,首先只有一个重复数字返回错误,因为它开始变大,只看到一个大模式。 第二个问题是存在嵌套模式,如第六和第七个示例列表,它将得到满足 使用嵌套循环并忽略模式的其余部分。
答案 0 :(得分:4)
作品(在样本的第4个元素中发现了拼写错误)
>>> seq_l = [
... [1,1,1,1,1,1],
... [4,1,4,1,4,1],
... [1,2,10,1,2,10],
... [1,1,1,1,1,4,1,4,1,20,9,8,1,1,1,1,1,4,1,4,1,20,9,8],
... [2,2,2,4,2,2,2,4,2,2,2,4,2,2,2,4],
... [1,1,1,13,21,45,3,3,1,16,4,1,4,1,1,1,24,15,1,1,1,13,21,45,3,3,1,16,4,1,4,1,1,1,24,15],
... [1,1,1,3,28,1,1,1,3,28,67,25,1,1,1,3,28,1,1,1,3,28,67,25]
... ]
>>>
>>> def rep_len(seq):
... s_len = len(seq)
... for i in range(1,s_len-1):
... if s_len%i == 0:
... j = s_len/i
... if seq == j*seq[:i]:
... return i
...
...
>>> [rep_len(seq) for seq in seq_l]
[1, 2, 3, 12, 4, 18, 12]
答案 1 :(得分:2)
如果将列表转换为字符串并不可行,那么使用正则表达式会使这个任务变得微不足道。
import re
lists = [
[1,1,1,1,1,1],
[4,1,4,1,4,1],
[1,2,10,1,2,10],
[1,1,1,1,1,4,1,4,1,20,9,8,1,1,1,1,1,4,1,4,1,20,9,8], #I think you had a typo in this one...
[2,2,2,4,2,2,2,4],
[1,1,1,13,21,45,3,3,1,16,4,1,4,1,1,1,24,15,1,1,1,13,21,45,3,3,1,16,4,1,4,1,1,1,24,15],
[1,1,1,3,28,1,1,1,3,28,67,25,1,1,1,3,28,1,1,1,3,28,67,25]
]
for l in lists:
s = "x".join(str(i) for i in l)
print s
match = re.match(r"^(?P<foo>.*)x?(?P=foo)", s)
if match:
print match.group('foo')
else:
print "****"
print
(?P<foo>.*)
创建一个名为“foo”的组,(?P=foo)
匹配该组。由于正则表达式是贪婪的,因此默认情况下会获得最长匹配。 “x?”只允许中间的单个x处理偶数/奇数长度。
答案 2 :(得分:1)
您可能可以执行collections.defaultdict(int)来保留所有子列表的计数,除非您知道有一些您不关心的子列表。在将子列表作为字典键之前将其转换为元组。
如果空间紧张,你可能会使用一系列布隆过滤器来到某个地方。对于长度为1的子序列,您将有一个布隆过滤器,对于长度为2的子序列,您将有另一个布隆过滤器。然后,获得冲突的最大布隆过滤器具有您的最大长度子列表。
答案 3 :(得分:0)
我认为你必须一次检查两个级别的序列。0..i == i..i*2
和0..i/2 != i/2..i
。
def lengths(seq):
for i in range(len(seq),1,-1):
if seq[0:i] == seq[i:i*2] and seq[0:i/2] != seq[i/2:i]:
return i
如果0..i
的两半相等,则表示您实际上是在比较两个连接模式。
答案 4 :(得分:0)
从第一个示例方法开始,您可以递归搜索子模式。
def lengths(seq):
for i in range(len(seq)-1,1,-1):
if seq[0:i] == seq[i:i*2]:
j = lengths(seq[0:i]) # Search pattern for sub pattern
if j < i and i % j == 0: # Found a smaller pattern; further, a longer repeated
# pattern length must be a multiple of the shorter pattern length
n = i/j # Number of pattern repetitions (might change to // if using Py3K)
for k in range(1, n): # Check that all the smaller patterns are the same
if seq[0:j] != seq[j*n:j*(n+1)]: # Stop when we find a mismatch
return i # Not a repetition of smaller pattern
else: return j # All the sub-patterns are the same, return the smaller length
else: return i # No smaller pattern
我觉得这个解决方案并不完全正确,但我会根据需要进行一些测试和编辑。 (快速注意:不应该在len(seq)-1处开始循环的初始化吗?如果不是,你将seq [0:len]与seq [len:len]进行比较,这看起来很愚蠢,并会导致递归无限循环。)
编辑:似乎排序类似于发布的相关问题发送者中的top answer,因此您最好去阅读。 ;)