How to test if one string is a subsequence of another?
本问题已经有最佳答案,请猛点这里访问。
如何测试一个字符串是否是另一个字符串的子序列?
与子字符串相比,这是一个较弱的条件。例如," iran"不是" ireland"的子字符串,而是子序列
更多示例:
-
"印度尼西亚"包含"印度"。
INDonesIA -
"罗马尼亚"包含"阿曼"。
rOMANia -
" malawi"包含" mali"。
MALawI
旅行:我的朋友喜欢文字游戏。昨天我们打了"国家内部的国家"。我很好奇我们是否错过了任何对。
编辑:如果您不熟悉子序列的数学定义
A subsequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements
1 2 3 4 5 6 7 8 9 10 | def is_subseq(x, y): it = iter(y) return all(any(c == ch for c in it) for ch in x) assert is_subseq('india', 'indonesia') assert is_subseq('oman', 'romania') assert is_subseq('mali', 'malawi') assert not is_subseq('mali', 'banana') assert not is_subseq('ais', 'indonesia') assert not is_subseq('ca', 'abc') |
也可用于任何可迭代项:
1 2 | assert is_subseq(['i', 'n', 'd', 'i', 'a'], ['i', 'n', 'd', 'o', 'n', 'e', 's', 'i', 'a']) |
更新
Stefan Pochmann提出了这个建议。
1 2 3 | def is_subseq(x, y): it = iter(y) return all(c in it for c in x) |
两个版本都使用迭代器;迭代器产生的项目不是上一次迭代中产生的。
例如:
1 2 3 4 5 6 7 8 9 10 11 12 | >>> it = iter([1,2,3,4]) >>> for x in it: ... print(x) ... break ... 1 >>> for x in it: # `1` is yielded in previous iteration. It's not yielded here. ... print(x) ... 2 3 4 |
只需继续寻找可能的子序列的下一个字符,就从最后一个发现的字符开始。一旦在字符串的其余部分找不到一个字符,就没有子序列。如果可以通过这种方式找到所有字符,则为:
1 2 3 4 5 6 | def is_subsequence(needle, haystack): current_pos = 0 for c in needle: current_pos = haystack.find(c, current_pos) + 1 if current_pos == 0 : return False return True |
我做到了
1 2 3 4 5 6 7 8 | def is_subsequence(x, y): """Test whether x is a subsequence of y""" x = list(x) for letter in y: if x and x[0] == letter: x.pop(0) return not x |
1 2 3 4 5 6 7 8 9 | def subsequence(seq, subseq): seq = seq.lower() subseq = subseq.lower() for char in subseq: try: seq = seq[seq.index(char)+1:] except: return False return True |