简体   繁体   English

查找最长连续子数组(未排序)-Python

[英]Find longest consecutive sub array (not sorted)-Python

v=[1,2,3,11,5,8,9,10,11,6,4] in the list above 1,2,3 are consecutive numbers (1st consecutive set). v=[1,2,3,11,5,8,9,10,11,6,4] 上面列表中的1,2,3是连续数(第1组连续数)。 8,9,10,11 are consecutive numbers (2nd set,largest one). 8,9,10,11 是连续的数字(第二组,最大的一组)。 How can I find this 2nd set?我怎样才能找到这第二套? This code below gives the consecutive numbers:下面的代码给出了连续的数字:

for i in range(len(v)-1):
    if v[i+1]==v[i]+1:
        if v[i-1]!=v[i]-1:
             print(v[i])
        print(v[i]+1)

Output:1,2,3,8,9,10,11

I was thinking of using something like below and add the outputs in a new list and then find out max value of the list.I can't think of a logic to combining those 2 ideas.我正在考虑使用类似下面的内容并将输出添加到一个新列表中,然后找出列表的最大值。我想不出将这两个想法结合起来的逻辑。

for i in range(len(v)-1):
    for j in range(i+1,len(v)):
        if v[j]-v[i]  

I looked at this example but I think that solution is different from what I am looking for.我查看了这个示例,但我认为该解决方案与我正在寻找的不同。 Thanks in advance for your time and suggestion.提前感谢您的时间和建议。

You can iterate over the list and keep appending the item to the potentially longest consecutive sub-list, and start a new one if the item not consecutive to the last item of the sub-list, and assign the sub-list as the new longest sub-list if it is longer than the current longest sub-list:您可以迭代列表并继续将项目附加到可能最长的连续子列表,如果该项目与子列表的最后一项不连续,则开始一个新的项目,并将子列表分配为新的最长的子列表,如果它比当前最长的子列表长:

candidate = []
longest = []
for i in v:
    if candidate and candidate[-1] != i - 1:
        if len(candidate) > len(longest):
            longest = candidate
        candidate = []
    candidate.append(i)
if len(candidate) > len(longest):
    longest = candidate

longest becomes: longest变成:

[8, 9, 10, 11]

You're pretty close.你很接近。 Store the current run as a list, update the best list when necessary and clear it whenever you break the run.将当前运行存储为一个列表,必要时更新最佳列表,并在您中断运行时清除它。 Care should be taken to include the last grouping if it appears at the very end of the list.如果最后一个分组出现在列表的最后,则应注意将其包括在内。

v = [1,2,3,11,5,8,9,10,11,6,4]
best = []
run = []

for i in range(1, len(v) + 1):
    run.append(v[i-1])

    if i == len(v) or v[i-1] + 1 != v[i]:
        if len(best) < len(run):
            best = run

        run = []

print(best)

Output:输出:

[8, 9, 10, 11]

You can use a sliding window shrinking the size and check if all numbers are in ascending order:您可以使用缩小大小的sliding window并检查所有数字是否按升序排列:

from itertools import islice

def window(seq, n=2):
    "Returns a sliding window (of width n) over data from the iterable"
    "   s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...                   "
    it = iter(seq)
    result = tuple(islice(it, n))
    if len(result) == n:
        yield result
    for elem in it:
        result = result[1:] + (elem,)
        yield result


def longestConsecutiveSeq(s):
  for seq in (window(s, i) for i in range(len(s)-1, 1, -1)):
    for subseq in seq:
      l = list(subseq)
      if all((y-x) == 1 for (x, y) in zip(l, l[1:])):
        return l

print(longestConsecutiveSeq([1,2,3,11,5,8,9,10,11,6,4]))

Result: [8, 9, 10, 11]结果: [8, 9, 10, 11]

This algorithm will stop on the first encounter of biggest size .该算法将在第一次遇到最大尺寸时停止。

You can use pandas:您可以使用熊猫:

import pandas as pd

v=[1,2,3,11,5,8,9,10,11,6,4]

s = pd.Series(v)

sgc = s.groupby(s.diff().ne(1).cumsum()).transform('count')

result = s[sgc == sgc.max()].tolist()

result

Output:输出:

[8, 9, 10, 11]

Details:细节:

Create a pandas series, use diff to calculate the difference from the previous value.创建一个熊猫系列,使用diff计算与前一个值的差异。 Next, use ne to create a boolean series where the difference is not equal to 1, then cumsum this boolean series to create groups, where consective values are all grouped together.接下来,使用ne创建一个差值不等于 1 的布尔系列,然后cumsum这个布尔系列进行cumsum以创建组,其中连续值都分组在一起。 Use, groupby with transform to a count of the group size to each record.使用groupbytransform为每个记录的组大小计数。 Lastly, use boolean indexing to only select parts of the series where the count in a group is equal to the max count of all groups.最后,使用布尔索引仅选择组中计数等于所有组的最大计数的系列部分。 Then convert to array using tolist .然后使用tolist转换为数组。

You can use differences between elements and their indices to group elements using the function 'groupby()':您可以使用元素及其索引之间的差异来使用函数“groupby()”对元素进行分组:

from itertools import groupby

l = [1, 2, 3, 11, 5, 8, 9, 10, 11, 6, 4]

gb = groupby(enumerate(l), lambda x: x[0] - x[1])
max(([i for _, i in g] for _, g in gb), key=len)
# [8, 9, 10, 11]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM