【问题标题】:Percentage of how similar strings are in Python? [closed]Python 中字符串相似度的百分比? [关闭]
【发布时间】:2013-12-22 04:26:02
【问题描述】:

我不知道如何编写一个程序,给出两个相同长度的字符串的相似度百分比。

例如,对于 abcdabce,它应该是 75%。

顺序很重要,我不希望 abcddcab 有 100%。

我知道 Levenshtein 模块可以做到这一点,但我想要一个可以做到这一点的程序。

【问题讨论】:

  • 不是重复的,请仔细阅读,在那个线程中他们要求一个模块,我想要一个可以做到的程序!
  • 好吧,在这里要求一个完整的程序交给你是不可接受的。您需要展示对问题的一些理解。所以我建议作为你研究的指针。
  • 好的,当我再次询问时,我会记住这一点。谢谢:)
  • 此外,Levenshtein 模块“一个程序”,您已经说过可以满足您的需求。在我链接的问题中获得最高票数的答案显示了您需要进行的函数调用。

标签: python string fuzzy-comparison


【解决方案1】:
>>> from difflib import SequenceMatcher
>>> SequenceMatcher(None, 'abcd', 'abce').ratio()
0.75

阅读文档了解更多信息。您可以阅读文档中的说明以了解如何自己执行此操作,但您最终会从头开始编写某种类型的对齐算法。

【讨论】:

  • 相信看他的例子,他其实是在找longets common substring
  • @Abhijit,是的,您在回答中说过 ;-) 但我不相信。 OP 暗示 Levenshtein 模块可以做他想做的事,但 Levenshtein 并不是最长的常见东西——它是“最小编辑距离”,这不是一回事。 difflib 算法类似于递归应用的最长公共子字符串。
  • 但是,SequenceMatcher(None, 'abcd', 'abce').ratio() = 0.25 而不是 0,如他的示例所示。所以这个问题令人困惑,OP 并不知道他真正想要什么:-)
  • 我同意这个问题不清楚。正如我的回答所说,SequenceMatcher(None, 'abcd', 'abce').ratio() 返回0.75(不是0.25),OP 说他们想要75%。我没有看到 OP 关于返回 0 的任何示例的任何内容。我看到的唯一其他情况是他们希望 abcddcab 返回 100%。
【解决方案2】:

相似这个词有不同的上下文,但是看看你的例子,我很确定,你正在寻找

Match% = 2* Longest_Common_Substring(a, b) / (len(a) + len(b)) * 100

只要谷歌搜索最长公共子串,你肯定会找到大量的 Python 实现。

这样的Python Implementation from Wikibook : Algorithm Implementation/Strings/Longest common substring如下

def longest_common_substring(s1, s2):
    m = [[0] * (1 + len(s2)) for i in xrange(1 + len(s1))]
    longest, x_longest = 0, 0
    for x in xrange(1, 1 + len(s1)):
        for y in xrange(1, 1 + len(s2)):
            if s1[x - 1] == s2[y - 1]:
                m[x][y] = m[x - 1][y - 1] + 1
                if m[x][y] > longest:
                    longest = m[x][y]
                    x_longest = x
            else:
                m[x][y] = 0
    return s1[x_longest - longest: x_longest]

用相似度函数包裹,结果符合你的预期

>>> def similarity(s1, s2):
     return 2. * len(longest_common_substring(s1, s2)) / (len(s1) + len(s2)) * 100

>>> similarity("abcd","abce")
75.0
>>> similarity("abcd","dcba")
25.0

【讨论】:

  • 这似乎是一个不错的方法,但是当 nstring 大小很大时,我们不能将其用于实际目的。它非常慢。相反,我们可以使用 SequenceMatcher 的最长子字符串方法来查找子字符串,并使用它周围的包装器,因为您定义了similarity() 方法。
【解决方案3】:

假设 s1 和 s2 的长度相同:

from numpy import mean
mean([s1[i]==s2[i] for i in xrange(len(s1))])

【讨论】:

    【解决方案4】:

    这个怎么样:

    >>> a = list('abce')
    >>> b = list('abcd')
    >>> ( 100 - (sum(i != j for i, j in zip(a, b)) / float(len(a))) * 100 )
    75.0
    >>> a = list('abce')
    >>> b = list('bdce')
    >>> ( 100 - (sum(i != j for i, j in zip(a, b)) / float(len(a))) * 100 )
    50.0
    >>>
    

    【讨论】:

      【解决方案5】:

      维基百科有Levenshtein_distance or Edit Distance 的伪代码 这是一个简单的算法。如果您遇到困难,为什么不试一试并提出具体问题。

      【讨论】:

        猜你喜欢
        • 2018-03-08
        • 1970-01-01
        • 2012-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多