寻找子序列(非连续)

use*_*061 15 python string

如果我有串needle,我想检查它是否连续为存在haystack,我可以使用:

if needle in haystack:
    ...
Run Code Online (Sandbox Code Playgroud)

在非连续子序列的情况下我可以使用什么?例:

>>> haystack = "abcde12345"
>>> needle1 = "ace13"
>>> needle2 = "123abc"
>>> is_subsequence(needle1, haystack)
True
>>> is_subsequence(needle2, haystack)  # order is important!
False
Run Code Online (Sandbox Code Playgroud)

Ish*_*ael 12

我不知道是否有内置功能,但手动操作相当简单

def exists(a, b):
    """checks if b exists in a as a subsequence"""
    pos = 0
    for ch in a:
        if pos < len(b) and ch == b[pos]:
            pos += 1
    return pos == len(b)
Run Code Online (Sandbox Code Playgroud)
>>> exists("moo", "mo")
True
>>> exists("moo", "oo")
True
>>> exists("moo", "ooo")
False
>>> exists("haystack", "hack")
True
>>> exists("haystack", "hach")
False
>>>
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢它具有线性时间复杂度 (2认同)

wim*_*wim 6

使用迭代器技巧:

it = iter(haystack)
all(x in it for x in needle)
Run Code Online (Sandbox Code Playgroud)

这只是另一个答案中提出的相同想法的简明版本。

  • 对于任何其他尝试内联“it”的人,也就是说,尝试像一行一样执行此操作:“all(x in iter(haystack) for x in Need)”,它不起作用,因为“iter(haystack)”每次都会重新实例化。 (3认同)

tob*_*s_k 5

另一种可能性:您可以为needle 和haystack 创建迭代器,然后从haystack-iterator 中弹出元素,直到找到needle 中的所有字符,或者迭代器耗尽。

def is_in(needle, haystack):
    try:
        iterator = iter(haystack)
        for char in needle:
            while next(iterator) != char:
                pass
        return True
    except StopIteration:
        return False
Run Code Online (Sandbox Code Playgroud)