当前位置:  开发笔记 > 编程语言 > 正文

确定序列是否在Python中的另一个序列中的最佳方法

如何解决《确定序列是否在Python中的另一个序列中的最佳方法》经验,为你挑选了3个好方法。

这是"字符串包含子字符串"问题到(更多)任意类型的概括.

给定一个序列(例如列表或元组),确定另一个序列是否在其中的最佳方法是什么?作为奖励,它应该返回子序列开始的元素的索引:

用法示例(序列中的序列):

>>> seq_in_seq([5,6],  [4,'a',3,5,6])
3
>>> seq_in_seq([5,7],  [4,'a',3,5,6])
-1 # or None, or whatever

到目前为止,我只是依靠蛮力,它似乎缓慢,丑陋,笨拙.



1> Federico A. ..:

我是第二个Knuth-Morris-Pratt算法.顺便说一下,你的问题(和KMP解决方案)正是Python Cookbook第2版​​中的配方5.13 .您可以在http://code.activestate.com/recipes/117214/找到相关代码.

它在给定的序列中找到所有正确的子序列,并且应该用作迭代器:

>>> for s in KnuthMorrisPratt([4,'a',3,5,6], [5,6]): print s
3
>>> for s in KnuthMorrisPratt([4,'a',3,5,6], [5,7]): print s
(nothing)


已知KMP在实践中的速度大约是天真算法的两倍.因此,对于大多数目的而言,它完全*不合适,尽管它具有良好的渐近最坏情况运行时间.
请注意,code.activestate上给出的KMP实现对于某些(可能是无代表性的输入)而言显着慢了30-500倍.基准测试看看愚蠢的内置方法是否优于大家似乎是一个好主意!

2> jfs..:

这是一种蛮力的方法O(n*m)(类似于@ mcella的答案).对于输入序列,它可能比纯Python中的Knuth-Morris-Pratt算法实现更快O(n+m)(参见@Gregg Lind答案).

#!/usr/bin/env python
def index(subseq, seq):
    """Return an index of `subseq`uence in the `seq`uence.

    Or `-1` if `subseq` is not a subsequence of the `seq`.

    The time complexity of the algorithm is O(n*m), where

        n, m = len(seq), len(subseq)

    >>> index([1,2], range(5))
    1
    >>> index(range(1, 6), range(5))
    -1
    >>> index(range(5), range(5))
    0
    >>> index([1,2], [0, 1, 0, 1, 2])
    3
    """
    i, n, m = -1, len(seq), len(subseq)
    try:
        while True:
            i = seq.index(subseq[0], i + 1, n - m + 1)
            if subseq == seq[i:i + m]:
               return i
    except ValueError:
        return -1

if __name__ == '__main__':
    import doctest; doctest.testmod()

我想知道这种情况下的小有多大?



3> nlucaroni..:

与字符串匹配先生相同... Knuth-Morris-Pratt字符串匹配

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有