确定两个字符串在Javascript中是不是相似?

Posted

技术标签:

【中文标题】确定两个字符串在Javascript中是不是相似?【英文标题】:Determine if two strings are similar in Javascript?确定两个字符串在Javascript中是否相似? 【发布时间】:2011-04-25 12:34:31 【问题描述】:

假设我有两个字符串,有什么方法可以检查它们是否至少 90% 相似?

var string1 = "theBoardmeetstoday,tomorrow51";
var string2 = "Board meets today, tomorrow";

谢谢,

泰根

【问题讨论】:

【参考方案1】:

Levenshtein distance 的***条目包含一个示例实现。

【讨论】:

您能否通过此示例提供指向该页面确切修订版本的链接(以防该示例从页面中删除?) 这里是页面的具体修改(从2010年10月14日开始):en.wikipedia.org/w/…【参考方案2】:

jsdifflib 是 Python 优秀的 difflib 库的 javascript 端口。

它有一个函数ratio(),它“返回[s]作为[0, 1]范围内的浮点数的序列相似性的度量。

【讨论】:

【参考方案3】:

String.levenshtein(MooTools 插件)

查看:http://mootools.net/forge/p/string_levenshtein

GitHub:https://github.com/thinkphp/String.levenshtein

此方法计算两个字符串之间的 Levenshtein 距离。在信息论和计算机科学中,Levenshtein 距离是衡量两个序列之间差异量(称为编辑距离)的度量。两个字符串之间的 Levenshtein 距离由将一个字符串转换为另一个给定字符串所需的最小操作数给出,其中可能的操作是插入、删除或替换单个字符。

Levenshtein 距离算法已用于:

拼写检查 语音识别 DNA 分析 抄袭检测

【讨论】:

这里是相同的代码,但没有 mootools 依赖 - gist.github.com/luchaninov/a5730c453129ae159dfc【参考方案4】:

还要考虑Dice's Coefficient,它被string-similarity github repo 及其对应的npm module 的创建者认为比Levenshtein 距离“基本上更好”。

其文档中的用法:

var stringSimilarity = require('string-similarity');

var similarity = stringSimilarity.compareTwoStrings('healed', 'sealed'); 

var matches = stringSimilarity.findBestMatch('healed', ['edward', 'sealed', 'theatre']);

【讨论】:

【参考方案5】:

借鉴其他人的答案,我写了一个简单的js函数stringsAreSimilar来做到这一点:

// https://github.com/thinkphp/String.levenshtein/blob/master/Source/String.levenshtein.js

function getStringDifference(stringA, stringB) 
  var cost = [],
    str1 = stringA,
    str2 = stringB,
    n = str1.length,
    m = str2.length,
    i, j;

  var minimum = function (a, b, c) 
    var min = a;
    if (b < min) 
      min = b;
    
    if (c < min) 
      min = c;
    
    return min;
  ;

  if (n == 0) 
    return;
  
  if (m == 0) 
    return;
  

  for (var i = 0; i <= n; i++) 
    cost[i] = [];
  

  for (i = 0; i <= n; i++) 
    cost[i][0] = i;
  

  for (j = 0; j <= m; j++) 
    cost[0][j] = j;
  

  for (i = 1; i <= n; i++) 

    var x = str1.charAt(i - 1);

    for (j = 1; j <= m; j++) 

      var y = str2.charAt(j - 1);

      if (x == y) 

        cost[i][j] = cost[i - 1][j - 1];

       else 

        cost[i][j] = 1 + minimum(cost[i - 1][j - 1], cost[i][j - 1], cost[i - 1][j]);
      

     //endfor

   //endfor

  return cost[n][m];


function stringsAreSimilar(stringA, stringB) 
  var difference = getStringDifference(stringA, stringB);
  debugConsoleLog("stringA" + stringA);
  debugConsoleLog("stringB" + stringB);
  debugConsoleLog("difference" + difference);
  
  return difference < 10;


var string1 = "theBoardmeetstoday,tomorrow51";
var string2 = "Board meets today, tomorrow";

if(similar) 
    console.log("they are similar");
 else 
    console.log("they are not similar");



【讨论】:

【参考方案6】:

所以我去年就尝试这样做。我读到Levenshtein distance 是 OP 在这里询问的解决方案。

我从一个线程中看到了一个代码,但没有得到太多支持。也许是因为它的时间复杂性(在 forloop 中有一个 forloop)。我试过了,它似乎对我有用。该函数返回一个分数,其中 0 是一个很好的匹配,另一方面,更高的分数意味着偏离一个接近的匹配。生病分享,也许有人可以扩展它或更好地解释它:

function editDistance(s1, s2) 
    s1 = s1.toLowerCase();
    s2 = s2.toLowerCase();

    var costs = new Array();
    for (var i = 0; i <= s1.length; i++) 
        var lastValue = i;
        for (var j = 0; j <= s2.length; j++) 
            if (i == 0) costs[j] = j;
            else 
                if (j > 0) 
                    var newValue = costs[j - 1];
                    if (s1.charAt(i - 1) != s2.charAt(j - 1))
                        newValue =
                            Math.min(Math.min(newValue, lastValue), costs[j]) +
                            1;
                    costs[j - 1] = lastValue;
                    lastValue = newValue;
                
            
        
        if (i > 0) costs[s2.length] = lastValue;
    
    return costs[s2.length];

祝你好运并分享您对此的想法 - 太棒了!干杯!

【讨论】:

以上是关于确定两个字符串在Javascript中是不是相似?的主要内容,如果未能解决你的问题,请参考以下文章

什么是确定 2 个字符串是不是“足够相似”的好指标

java 一个实用程序类,它使用各种方法来确定两个字符串之间的相似性。

确定字符串是不是在 JavaScript 的列表中

python中是不是有用于计算两个字符串相似度的函数

给定单词相似度推断句子相似度

初学者javascript中非常相似的术语之间的逻辑差异