如何检查有序的非连续子序列是否在数组中?蟒蛇

时间:2017-07-09 23:58:19

标签: python arrays algorithm search subsequence

如果还没有被要求,我会感到惊讶。

我们说我有一个数组[5,6,7,29,34],我想检查序列5,6,7是否出现在它(它做了)。订单很重要。

我该怎么做?

3 个答案:

答案 0 :(得分:4)

只是为了好玩,这是一个快速(非常快)和脏(非常脏)的解决方案(有点缺陷,所以不要真的使用它):

>>> str([5,6,7]).strip('[]') in str([5,6,7,29,34])
True

RightWay™可能会使用list.index()来查找第一个元素的候选匹配项,然后验证与切片和列表相等的完全匹配:

>>> def issubsequence(sub, seq):
        i = -1
        while True:
            try:
                i = seq.index(sub[0], i+1)  # locate first character
            except ValueError:
                return False
            if seq[i : i+len(sub)] == sub:  # verify full match
                return True         

>>> issubsequence([5, 6, 7], [5,6,7,29,34])
True
>>> issubsequence([5, 20, 7], [5,6,7,29,34])
False

编辑:OP在评论中澄清,子序列必须按顺序排列,但不必处于连续位置。这有一个不同的,更复杂的解决方案,已在这里得到解答:How do you check if one array is a subsequence of another?

答案 1 :(得分:2)

这是一个很好的解决方案:

def is_sublist(a, b):
    if not a: return True
    if not b: return False
    return b[:len(a)] == a or is_sublist(a, b[1:])

如Stefan Pochmann所述,这可以改写为:

def is_sublist(a, b):
    return b[:len(a)] == a or bool(b) and is_sublist(a, b[1:])

答案 2 :(得分:0)

这是一个对任何可迭代对象都有效(高效!)的解决方案:

import collections
import itertools

def consume(iterator, n=None):
    """Advance the iterator n-steps ahead. If n is none, consume entirely."""
    # Use functions that consume iterators at C speed.
    if n is None:
        # feed the entire iterator into a zero-length deque
        collections.deque(iterator, maxlen=0)
    else:
        # advance to the empty slice starting at position n
        next(islice(iterator, n, n), None)

def is_slice(seq, subseq):
    """Returns whether subseq is a contiguous subsequence of seq."""
    subseq = tuple(subseq)  # len(subseq) is needed so we make it a tuple.
    seq_window = itertools.tee(seq, n=len(subseq))
    for steps, it in enumerate(seq_window):
        # advance each iterator to point to subsequent values in seq.
        consume(it, n=steps)
    return any(subseq == seq_slice for seq_slice in izip(*seq_window))

consume来自itertools recipes