【问题标题】:Python: Compare two strings and return the longest segment that they have in commonPython:比较两个字符串并返回它们共有的最长段
【发布时间】:2013-03-19 16:39:35
【问题描述】:

作为一名 Python 新手,我编写了一个工作函数,它将比较两个字符串并搜索两个字符串共享的最长子字符串。例如,当函数比较“goggle”和“google”时,它会将“go”和“gle”识别为两个常见的子字符串(不包括单个字母),但只会返回“gle”,因为它是最长的。

我想知道我的代码的任何部分是否可以改进/重写,因为它可能被认为是冗长且令人费解的。我也很高兴看到解决方案的其他方法。提前致谢!

def longsub(string1, string2):
    sublist = []
    i=j=a=b=count=length=0

    while i < len(string1):
        while j < len(string2):
            if string1[i:a+1] == string2[j:b+1] and (a+1) <= len(string1) and (b+1) <= len(string2):
                a+=1
                b+=1
                count+=1
            else:
                if count > 0:
                    sublist.append(string1[i:a])
                count = 0
                j+=1
                b=j
                a=i
        j=b=0
        i+=1
        a=i

    while len(sublist) > 1:
        for each in sublist:
            if len(each) >= length:
                length = len(each)
            else:
                sublist.remove(each)

    return sublist[0]

编辑:比较“goggle”和“google”可能是一个不好的例子,因为它们的长度相同,最长的公共段位于相同的位置。实际的输入会更接近这个:“xabcdkejp”和“zkdieaboabcd”。正确的输出应该是“abcd”。

【问题讨论】:

    标签: python string compare substring


    【解决方案1】:

    标准库中实际上恰好有一个函数:difflib.SequencMatcher.find_longest_match

    【讨论】:

    • 我现在没有时间写一个例子,但是文档很清楚。午饭回来后,我会尽量记住添加一个示例(除非其他人想先编辑一个 [hint hint])
    • 看起来SamiN 提供了一个示例,所以我不必:)
    【解决方案2】:

    编辑:该算法仅适用于相同索引中的词段最长的情况

    你可以只用一个循环就可以逃脱。使用辅助变量。像这样的东西(需要重构)http://codepad.org/qErRBPav:

    word1 = "google"
    word2 = "goggle"
    
    longestSegment = ""
    tempSegment = ""
    
    for i in range(len(word1)):
        if word1[i] == word2[i]:
            tempSegment += word1[i]
        else: tempSegment = ""
    
        if len(tempSegment) > len(longestSegment):
            longestSegment = tempSegment
    
    print longestSegment # "gle"
    

    编辑:mgilson 的使用find_longest_match 的建议(适用于不同位置的段):

    from difflib import SequenceMatcher
    
    word1 = "google"
    word2 = "goggle"
    
    s = SequenceMatcher(None, word1, word2)
    match = s.find_longest_match(0, len(word1), 0, len(word2))
    
    print word1[match.a:(match.b+match.size)] # "gle"
    

    【讨论】:

    • 非常感谢,它非常简单直观。谢谢!
    • 附带说明,我认为您的第一个解决方案实际上并不奏效。例如采取太的话:'google''gleblh'。最长的公共子字符串是gle,但我认为您的函数不会选择它。
    • 嗨,Sami,如果这两个字符串更加混乱,您将如何更改代码以反映这一点?很抱歉没有澄清这一点,因为这就是我在自己的代码中进行切片的原因。
    • 同时建议看一下find_longest_match的源码。
    猜你喜欢
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-06
    • 2019-03-04
    相关资源
    最近更新 更多