如何在数组或整数列表中找到重复的整数对的模式?

时间:2022-04-18 21:46:36

I have below like array or list:

我有下面像数组或列表:

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]

I need to find the repeating (2,-1) pattern sequence, if this pattern is successive,then report the successive sequence till it break off, i.e. output B as below

我需要找到重复的(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]]

The first (2,-1) pattern sequence is [2, -1, 2, -1, 2, -1, 2, -1, 2, -1, 2, -1, 2, -1], then break; The 2nd (2,-1) pattern sequence is [2, -1, 2, -1, 2, -1], then break; The last (2,-1) pattern sequence is also [2, -1, 2, -1, 2, -1], and break;

第一个(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]和break;

What is the best way to get this result?

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

Please note that using (2,-1) is an example - I'd like to be able to do this for an arbitrary pair of integers (e.g. (3,-1) or (3,4).

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

3 个解决方案

#1


3  

Assuming you are looking for B to contain a list of all patterns in A that begin on integer x (default at 2), end on integer y (default at -1), and alternate between the values x and y, then here's how you can generate B:

假设您正在寻找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

#2


3  

I came up with this solution:

我提出了这个解决方案:

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]

It works by iterating once through the list and matching the pattern as long as possible. Instead of storing the actual contents of the part, it just stores the length of each subsequent part. Since we are looking for repetitions of the pattern, we can completely construct the repeated pattern at the very end.

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

The way it works, it also allows for arbitrary length patterns, and is not restricted to 2-element patterns.

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

Used, it looks like this:

使用,它看起来像这样:

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

If you are a fan of crazy one-liners, you can also look at this solution using regular expressions. I do not recommend it, since it’s not only barely readable but also not really efficient. It also supports arbitrary length patterns, but it also requires that the list is a list of integers, while the above solution can work with any kinds of lists. So this is really just for the curious mind:

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

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

#3


1  

Correct me if i didn't understand you correctly. Hope code below suits your needs:

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

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

#1


3  

Assuming you are looking for B to contain a list of all patterns in A that begin on integer x (default at 2), end on integer y (default at -1), and alternate between the values x and y, then here's how you can generate B:

假设您正在寻找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

#2


3  

I came up with this solution:

我提出了这个解决方案:

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]

It works by iterating once through the list and matching the pattern as long as possible. Instead of storing the actual contents of the part, it just stores the length of each subsequent part. Since we are looking for repetitions of the pattern, we can completely construct the repeated pattern at the very end.

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

The way it works, it also allows for arbitrary length patterns, and is not restricted to 2-element patterns.

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

Used, it looks like this:

使用,它看起来像这样:

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

If you are a fan of crazy one-liners, you can also look at this solution using regular expressions. I do not recommend it, since it’s not only barely readable but also not really efficient. It also supports arbitrary length patterns, but it also requires that the list is a list of integers, while the above solution can work with any kinds of lists. So this is really just for the curious mind:

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

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

#3


1  

Correct me if i didn't understand you correctly. Hope code below suits your needs:

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

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