从序列[PYTHON]中提取最大长度的子序列

时间:2016-11-18 00:57:28

标签: python list python-3.x subsequence

我有一系列值[1,2,3,4,1,5,1,6,7],我必须找到增加长度的最长子序列。但是,该函数一旦达到低于前一个的数字就需要停止计数。在这种情况下,这个顺序的答案是[1,2,3,4]。因为它在重置之前有4个值。我将如何为此编写Python代码?

注意:找到"最长的增长子序列"似乎是一个常见的挑战,所以在网上搜索我发现很多解决方案都会计算整个序列的长度,并返回增加值的子序列,忽略任何减少,所以在这种情况下它会返回[1,2 ,3,4,5,6,7]。这不是我想要的。

它需要对每个子序列进行计数,并在达到低于前一个数字的数字时重置计数。然后需要比较所有计算的子序列,并返回最长的子序列。

提前致谢。

3 个答案:

答案 0 :(得分:1)

考虑一个生成所有可能的升序子序列的函数,你将从一个空列表开始,添加项目,直到一个元素少于(或等于?)前一个元素保存(yield)子序列并使用新的子序列重新启动。

使用生成器的一个实现可能是:

def all_ascending_subsequences(sequence):
    #use an iterator so we can pull out the first element without slicing
    seq = iter(sequence)

    try: #NOTE 1
        last = next(seq)  # grab the first element from the sequence
    except StopIteration: # or if there are none just return
        #yield [] #NOTE 2
        return

    sub = [last]
    for value in seq:
        if value > last: #or check if their difference is exactly 1 etc.
            sub.append(value)
        else: #end of the subsequence, yield it and reset sub
            yield sub
            sub = [value]
        last = value

    #after the loop we send the final subsequence
    yield sub

关于处理空序列的两个注释:

  1. 要完成生成器,StopIteration需要 因此,我们可以让next(seq)中的那个突然出来 - 但是当from __future__ import generator_stop进入时 效果它会导致RuntimeError以便将来兼容我们 需要明确地抓住它return
  2. 正如我写的那样,它将空列表传递给了 all_ascending_subsequences不会生成任何值,但可能不生成值 是理想的行为。随意取消注释yield [] 传递空列表时生成一个空列表。
  3. 然后,您可以通过key=len

    在结果上调用max来获得最长时间
    b =  [1,2,3,4,1,5,1,6,7]
    
    result = max(all_ascending_subsequences(b),key=len)
    print("longest is", result)
    
    #print(*all_ascending_subsequences(b))
    

答案 1 :(得分:0)

b = [4,1,6,3,4,5,6,7,3,9,1,0]

def findsub(a):
  start = -1
  count = 0
  cur = a[0]
  for i, n in enumerate(a):
    if n is cur+1:
      if start is -1:
        start = i - 2
        count=1
      count+=1
      cur = n
    if n < cur and count > 1:
      return [a[j] for j in range(start,start+count+1)]


print findsub(b)

有点草率的算法,但我相信它能做到你想要的。通常我不会简单地向您展示代码,但我怀疑这是您想要的,我希望您可以从中学习,并从您学到的东西中创建自己的代码。

看起来稍微好一些,因为我不喜欢这样:

b = [1,2,0,1,2,3,4,5]

def findsub(a):
  answer = [a[0]]
  for i in a[1:]:
    if answer[-1] + 1 is i:
      answer.append(i)
    if not len(answer) > 1:
      answer = [i]
    elif i < answer[-1] and len(answer) > 1:
      return answer
  return answer



print findsub(b)

答案 2 :(得分:0)

您需要执行以下操作:

  1. 创建一个给定列表的函数W,返回从列表开头不严格增加的最后一项的索引。

    • 例如,根据以下列表:[1,2,3,4,1,2,3], [4,2,1], [5,6,7,8],它应分别为每个列表返回414
  2. 创建变量maxim并将值设置为0

  3. 反复执行以下操作,直至列表为空
    • 在列表中调用您的函数W,然后拨打返回值x
    • 如果x大于maxim
      • maxim设为x
      • 此时,如果您希望存储此序列,可以使用list-slice notation获取列表中包含序列的部分。
    • 从列表中删除列表中的那部分
  4. 最后,打印maxim,如果您要存储包含最长序列的列表部分,则打印最后一个