Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何检查数组中是否存在有序的非连续子序列?python_Python_Arrays_Algorithm_Search_Subsequence - Fatal编程技术网

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

如何检查数组中是否存在有序的非连续子序列?python,python,arrays,algorithm,search,subsequence,Python,Arrays,Algorithm,Search,Subsequence,如果还没有人问我,我会很惊讶 假设我有一个数组[5,6,7,29,34],我想检查序列5,6,7是否出现在其中(它确实出现了)。秩序确实重要 我该怎么做?这里有一个很好的解决方案: 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 i

如果还没有人问我,我会很惊讶

假设我有一个数组
[5,6,7,29,34]
,我想检查序列
5,6,7
是否出现在其中(它确实出现了)。秩序确实重要


我该怎么做?

这里有一个很好的解决方案:

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

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

正道™ 可能用于查找第一个元素的候选匹配项,然后使用切片和列表相等性验证完全匹配:

>>> 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在注释中阐明,子序列必须有序,但不必处于连续位置。这有一个不同的、更复杂的解决方案,这里已经给出了答案:

这里有一个解决方案,可以(有效地!)在任何一对iterable对象上工作:

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

消费
来自。

像子字符串还是像子序列?我假设顺序很重要?<代码>(1, 2)<代码>匹配<代码> [ 1, 2, 3,4 ] <代码>但不<代码> [ 3, 2, 1,4 ] < /代码> @ @ Chordin Dead,命令事项。您是否考虑<代码> [5]、7]、“29”< /代码> <代码>“子数组”[5,6,7,29,34 ] < /代码>?这是一个子序列。@RaymondHettinger你不知道子序列和子序列的区别吗?我很惊讶,“漂亮”的解决方案。。。你太自信了:)。。。更严重的是,如果不是a,您甚至可以执行
:返回True;如果不是b:return False
…完美,如果有人想要的话,您可能也可以将其lambda化。如果您要使用它,请记住它会很快达到递归限制。1000个元素的列表是不允许的。只需返回b[:len(A)]==A或bool(b)和is_子列表(A,b[1:])。你的两个“如果”没有真正的帮助。嗯,对于
str([5,6,7]),这也表示
True
。str([55,6,7,29,34])中的strip(“[])
。并且你添加的解决方案失败
issubsequence([1,3],[1,2,3])
。它说的是
False
而不是正确的
True
@StefanPochmann不,它不是。我得到的输出是
False
。@StefanPochmann OP只想匹配与子列表顺序相同的子序列。对吗?这就是他告诉我的:“@ChristianDean是的,顺序很重要。”@ChristianDean是的,显然很多人不知道维基百科关于子字符串和子序列的文章马上引用了另一个,并警告人们不应该混淆它们:-)
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))