查找列表中最小的重复片段

时间:2019-02-08 09:37:28

标签: python python-3.x

我有一些整数列表,例如:

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”。

4 个答案:

答案 0 :(得分:3)

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 % 20)以及每个奇数索引是否等于第二个元素(5 % 21)。如果您已完成所有操作,则模式是前两个元素,因此请返回inp[:2],否则,请尝试使用3,依此类推。

您可以执行range(1, len(inp)+1),然后for循环将处理inp不包含重复模式的情况,但是您必须不必要地遍历整个{{ 1}}。而且,您仍然必须在末尾使用inp来处理return []是空列表。

我返回列表的副本(inp),而不是列表以具有一致的行为。如果我用inp[:]返回了原始列表,并且有人在一个没有重复模式的列表上调用了该函数(即他们的重复模式是原始列表),然后对重复模式做了一些操作,它将修改以及他们的原始列表。

return inp

答案 1 :(得分:1)

以下代码是您的解决方案的重做,解决了一些问题:

  1. 您发布的解决方案无法处理您自己的'abcabcab'示例。

  2. 即使找到有效结果,您的解决方案也会继续进行处理,然后对有效和无效结果进行过滤。相反,一旦找到有效结果,我们将对其进行处理并返回。其他有效结果和无效结果将被忽略。

  3. @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='')

答案 2 :(得分:0)

解决方案

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)))
  

“结果:[8,9]”。

答案 3 :(得分:-1)

简单解决方案:

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]