我怎样才能在数组或整数列表中找到重复的整数对的模式?

时间:2015-12-17 07:47:41

标签: python arrays list pattern-matching

我有下面的数组或列表:

A=[2,-1,2,-1,2,-1,2,-1,2,-1,2,-1,2,-1,1,-1,2,-1,2,-1,2,-1,1,-1,2,-1,2,-1,2,-1]

我需要找到重复的(2,-1)模式序列,如果这个模式是连续的,那么报告连续的序列直到它中断,即输出B如下

B=[[2, -1, 2, -1, 2, -1, 2, -1, 2, -1, 2, -1, 2, -1],[2, -1, 2, -1, 2, -1],
[2, -1, 2, -1, 2, -1]]

第一个(2,-1)模式序列为[2, -1, 2, -1, 2, -1, 2, -1, 2, -1, 2, -1, 2, -1],然后中断; 第二个(2,-1)模式序列为[2, -1, 2, -1, 2, -1],然后中断; 最后的(2,-1)模式序列也是[2, -1, 2, -1, 2, -1],并且中断;

获得此结果的最佳方法是什么?

请注意,使用(2,-1)是一个示例 - 我希望能够为任意一对整数(例如(3,-1)或(3,4)执行此操作。

3 个答案:

答案 0 :(得分:3)

假设您正在寻找B包含A中以整数x开始的所有模式的列表(默认为2),结束于整数y(默认为-1),并在值x和y之间交替,则以下是如何生成B:

def special_pattern(A, x=2, y=-1):
    B = []
    temp = []
    flag = 0
    for elem in A:
        if elem == x and flag == 0:
            flag = 1
        elif elem == y and flag == 1:
            temp.extend([x, y])
            flag = 0
        else:
            if temp != []:
                B.append(temp)
                temp = []
            if not(elem == x and flag == 1): 
                flag = 0
    if temp != []:
        B.append(temp)
    return B

答案 1 :(得分:3)

我提出了这个解决方案:

def find_patterns (lst, pattern):
    pattern = list(pattern)
    patternLength = len(pattern)
    lengths = []
    i, currentLength = 0, 0
    while i <= len(lst) - patternLength:
        if lst[i:i + patternLength] == pattern:
            currentLength += 1
            i += patternLength
        else:
            i += 1
            if currentLength > 0:
                lengths.append(currentLength)
                currentLength = 0
    if currentLength > 0:
        lengths.append(currentLength)
    return [pattern * x for x in lengths]

它通过在列表中迭代一次并尽可能地匹配模式来工作。它不是存储零件的实际内容,而是存储每个后续零件的长度。由于我们正在寻找模式的重复,我们可以在最后完全构造重复模式。

它的工作方式,它也允许任意长度的模式,并不限于2元素模式。

使用,它看起来像这样:

>>> find_patterns([2, -1, 2, -1, 2, -1, 1, -1, 2, -1, 2, -1, 2, 2, -1], (2, -1))
[[2, -1, 2, -1, 2, -1], [2, -1, 2, -1], [2, -1]]
>>> find_patterns([1, 2, 1, 2, 1, 2, 3, 4, 3, 4], (1, 2))
[[1, 2, 1, 2, 1, 2]]
>>> find_patterns([1, 2, 3, 1, 2, 3, 4, 1, 2, 3], (1, 2, 3))
[[1, 2, 3, 1, 2, 3], [1, 2, 3]]

如果您是疯狂单行的粉丝,您还可以使用正则表达式查看此解决方案。我不推荐它,因为它不仅几乎不可读,而且效率也不高。它还支持任意长度模式,但它还要求列表是整数列表,而上述解决方案可以使用任何类型的列表。所以这真的只是为了好奇的心灵:

def find_patterns (lst, pattern):
    return [[int(x) for x in m.split(';')] for m in re.findall('({0}(?:;{0})*)'.format(';'.join(map(str, pattern))), ';'.join(map(str, lst)))]

答案 2 :(得分:1)

如果我没有正确理解你,请纠正我。以下希望代码符合您的需求:

A=[2, -1, 2, -1, 2, -1, 2, -1, 2, -1, 2, -1, 2, -1, 1, -1, 2, -1, 2, -1, 2, -1, 1, -1, 2, -1, 2, -1, 2, -1]
B=[[2, -1, 2, -1, 2, -1, 2, -1, 2, -1, 2, -1, 2, -1],[2, -1, 2, -1, 2, -1],
[2, -1, 2, -1, 2, -1]]

A_str = ''.join(str(x) for x in A)
for item in B:
    if ''.join(str(x) for x in item) in A_str:
        print item