【问题标题】:Emulate Python str.find(substring) using iteration but not built-in functions使用迭代而不是内置函数模拟 Python str.find(substring)
【发布时间】:2014-07-12 02:42:13
【问题描述】:

如何在 Python 中不使用 str.find() 找到子字符串在字符串中的位置?我应该如何循环它?

def find substring(string,substring):
     for i in xrange(len(string)):
        if string[i]==substring[0]:
          print i
        else: print false

例如,当string = "ATACGTG"substring = "ACGT" 时,它应该返回2。我想了解str.find() 的工作原理

【问题讨论】:

  • 我的解决方案如何为您服务?
  • index 和 find 基本一样。我想在不使用任何内置函数的情况下解决问题。我的想法是:如果子字符串在字符串中,则在 string[i]=substring[0] 处找到 i 并返回 i。我对python不熟悉
  • 您使用的是内置函数 xrange 和 len,您的意思是没有字符串方法吗?
  • 构建自己的find 函数将不可避免地慢得多,因为许多Python 的内置函数都针对速度进行了优化和/或用C 编写。创建自己的函数的原因是什么?您似乎正在搜索速度可能至关重要的基因组数据。
  • 查看这个问题了解find在Python中的实际工作原理stackoverflow.com/questions/681649/…

标签: python string find substring


【解决方案1】:

您可以使用Boyer-MooreKnuth-Morris-Pratt。两者都创建表格以预先计算每次未命中时的更快移动。 B-M 页面有一个 python 实现。并且这两个页面都引用了其他字符串搜索算法。

【讨论】:

  • 其他问题的答案表明 Python find 实现基于 Boyer-Moore - stackoverflow.com/questions/681649/…
  • 是的,我敢肯定。不过,我不确定你在做什么。这 not 是否是一个好的答案,因为它在 python 中复制了 C 中的底层实现?如果你必须在 python 中从头开始实现string.find,你会怎么做?
  • 这对我来说似乎是一个高度相关的答案,这就是我投票的原因。我只是提供更多信息 - 如果听起来很关键,请见谅。
【解决方案2】:

我想不出没有任何内置函数的方法。

我可以:

def find_substring(string, substring):

    def starts_with(string, substring):
        while True:
            if substring == '':
                return True

            if string == '' or string[0] != substring[0]:
                return False

            string, substring = string[1:], substring[1:]

    n = 0

    while string != '' and substring != '':

        if starts_with(string, substring):
            return n

        string = string[1:]

        n += 1

    return -1

print(find_substring('ATACGTG', 'ACGT'))

即避免使用内置的len()range() 等。不使用内置的len() 我们会失去一些效率,因为我们本可以更快地完成。 OP 指定的迭代,上面使用,但递归变体更紧凑:

def find_substring(string, substring, n=0):

    def starts_with(string, substring):
        if substring == '':
            return True

        if string == '' or string[0] != substring[0]:
            return False

        return starts_with(string[1:], substring[1:])

    if string == '' or substring == '':
        return -1

    if starts_with(string, substring):
        return n

    return find_substring(string[1:], substring, n + 1)

print(find_substring('ATACGTG', 'ACGT'))

【讨论】:

    【解决方案3】:

    在不使用find的约束下,可以使用str.index,如果没有找到子字符串则返回ValueError:

    def find_substring(a_string, substring):
        try:
            print(a_string.index(substring))
        except ValueError:
            print('Not Found')
    

    及用法:

    >>> find_substring('foo bar baz', 'bar')
    4
    >>> find_substring('foo bar baz', 'quux')
    Not Found
    

    如果你必须循环,你可以这样做,它沿着字符串滑动,然后用匹配的第一个字符检查字符串的其余部分是否以子字符串开头,这是一个匹配:

    def find_substring(a_string, substring):
        for i, c in enumerate(a_string):
            if c == substring[0] and a_string[i:].startswith(substring):
                print(i)
                return
        else: 
            print(False)
    

    不使用字符串方法:

    def find_substring(a_string, substring):
        for i in range(len(a_string)):
            if a_string[i] == substring[0] and a_string[i:i+len(substring)] == substring:
                print(i)
                return
        else: 
            print(False)
    

    我想不出没有任何内置函数的方法。

    【讨论】:

    • index 和 find 基本一样。我想在不使用任何内置函数的情况下解决问题
    • @Nur 这个怎么样,没有索引?
    猜你喜欢
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    相关资源
    最近更新 更多