我有一些包含整数的列表,例如:
l1 = [8,9,8,9,8,9,8],
l2 = [3,4,2,4,3]
我的目的是将其切分成最小重复段。因此:
output_l1 = [8,9]
output_l2 = [3,4,2,4]
最大的问题是序列不总是每次完全结束。所以不是
'abcabcabc'
而只是
'abcabcab'。
我有一些包含整数的列表,例如:
l1 = [8,9,8,9,8,9,8],
l2 = [3,4,2,4,3]
我的目的是将其切分成最小重复段。因此:
output_l1 = [8,9]
output_l2 = [3,4,2,4]
最大的问题是序列不总是每次完全结束。所以不是
'abcabcabc'
而只是
'abcabcab'。
def shortest_repeating_sequence(inp):
for i in range(1, len(inp)):
if all(inp[j] == inp[j % i] for j in range(i, len(inp))):
return inp[:i]
# inp doesn't have a repeating pattern if we got this far
return inp[:]
这段代码的时间复杂度为 O(n^2)。最坏情况是其中一个元素重复很多次,然后在末尾出现了破坏模式的东西,例如 [1, 1, 1, 1, 1, 1, 1, 1, 1, 8]
。
从第一个元素1
开始,遍历整个列表检查每个inp[i]
是否等于inp[i % 1]
。任何数% 1
都等于0
,因此您正在检查输入中的每个项是否等于输入中的第一个项。如果所有项都等于第一个元素,则重复模式是仅由第一个元素组成的列表,因此我们返回inp[:1]
。
all()
一旦找到 False
就停止),那么尝试使用 2
。现在你正在检查每个偶数索引处的元素是否等于第一个元素(4%2
是 0
),以及每个奇数索引是否等于第二个元素(5%2
是 1
)。如果你通过了这一步,该模式就是前两个元素,所以返回 inp[:2]
,否则再尝试使用 3
等等。range(1, len(inp)+1)
,然后 for
循环将处理 inp
不包含重复模式的情况,但最后你仍需要无用地遍历整个 inp
。而且你仍然必须在末尾加上 return []
来处理 inp
是空列表的情况。inp[:]
),以保持一致的行为。如果我返回原始列表 return inp
,并且有人在不具有重复模式的列表上调用该函数(即它们的重复模式是原始列表),然后对重复模式进行操作,它也会修改他们的原始列表。shortest_repeating_sequence([4, 2, 7, 4, 6]) # no pattern
[4, 2, 7, 4, 6]
shortest_repeating_sequence([2, 3, 1, 2, 3]) # pattern doesn't repeat fully
[2, 3, 1]
shortest_repeating_sequence([2, 3, 1, 2]) # pattern doesn't repeat fully
[2, 3, 1]
shortest_repeating_sequence([8, 9, 8, 9, 8, 9, 8])
[8, 9]
shortest_repeating_sequence([1, 1, 1, 1, 1])
[1]
shortest_repeating_sequence([])
[]
您发布的解决方案无法处理您自己的'abcabcab'
示例。
您的解决方案即使在找到有效结果后仍然继续处理,然后过滤有效和非有效结果。相反,一旦找到有效结果,我们就会处理并返回它。其他有效结果和非有效结果都将被忽略。
@Boris提出的如果没有重复模式则返回输入的问题。
代码
def repeated_piece(target):
target = list(target)
length = len(target)
for final in range(1, length):
result = []
while len(result) < length:
for i in target[:final]:
result.append(i)
if result[:length] == target:
return result[:final]
return target
l1 = [8, 9, 8, 9, 8, 9, 8]
l2 = [3, 4, 2, 4, 3]
l3 = 'abcabcab'
l4 = [1, 2, 3]
print(*repeated_piece(l1), sep='')
print(*repeated_piece(l2), sep='')
print(*repeated_piece(l3), sep='')
print(*repeated_piece(l4), sep='')
输出
% python3 test.py
89
3424
abc
123
%
你仍然可以使用:
print(''.join(map(str, repeated_piece(l1))))
如果你对更简单的 Python 3 语法感到不舒服:
print(*repeated_piece(l1), sep='')
target = [8,9,8,9,8,9,8]
length = len(target)
result = []
results = [] * length
for j in range(1, length):
result = []
while len(result) < length:
for i in target[:j]:
result.append(i)
results.append(result)
final = []
for i in range(0, len(results)):
if results[i][:length] == target:
final.append(1)
else:
final.append(0)
if 1 in final:
solution = results[final.index(1)][:final.index(1)+1]
else:
solution = target
int(''.join(map(str, solution)))
简单解决方案:
def get_unique_items_list(some_list):
new_list = []
for i in range(len(some_list)):
if not some_list[i] in new_list:
new_list.append(some_list[i])
return new_list
l1 = [8,9,8,9,8,9,8]
l2 = [3,4,2,4,3]
print(get_unique_items_list(l1))
print(get_unique_items_list(l2))
#### Output ####
# [8, 9]
# [3, 4, 2]