Нахождение подпоследовательности (непоследовательный)
Если у меня есть строковая needle
и я хочу проверить, существует ли она непрерывно как подстрока в haystack
, я могу использовать:
if needle in haystack:
...
Что я могу использовать в случае непоследовательной подпоследовательности? Пример:
>>> haystack = "abcde12345"
>>> needle1 = "ace13"
>>> needle2 = "123abc"
>>> is_subsequence(needle1, haystack)
True
>>> is_subsequence(needle2, haystack) # order is important!
False
Ответы
Ответ 1
Я не знаю, есть ли встроенная функция, но это довольно просто сделать вручную
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)
>>> exists("moo", "mo")
True
>>> exists("moo", "oo")
True
>>> exists("moo", "ooo")
False
>>> exists("haystack", "hack")
True
>>> exists("haystack", "hach")
False
>>>
Ответ 2
Используя трюк итератора:
it = iter(haystack)
all(x in it for x in needle)
Это только краткий вариант той же идеи, представленной в другом ответе.
Ответ 3
Другая возможность: вы можете создавать итераторы как для иглы, так и для сена, а затем добавлять элементы из итератора сена, пока не будут найдены все символы в игле, или итератор исчерпан.
def is_in(needle, haystack):
try:
iterator = iter(haystack)
for char in needle:
while next(iterator) != char:
pass
return True
except StopIteration:
return False