比较字符串 Javascript 返回可能的百分比

2024-02-23

我正在寻找一个 JavaScript 函数,它可以比较两个字符串并返回它们相似的可能性。我看过 soundex 但对于多单词字符串或非名称来说并不是很好。我正在寻找一个类似的函数:

    function compare(strA,strB){
    
    }
    
    compare("Apples","apple") = Some X Percentage.

该函数适用于所有类型的字符串,包括数字、多字值和名称。也许我可以使用一个简单的算法?

最终这些都没有达到我的目的,所以我使用了这个:

     function compare(c, u) {
            var incept = false;
            var ca = c.split(",");
            u = clean(u);
            //ca = correct answer array (Collection of all correct answer)
            //caa = a single correct answer word array (collection of words of a single correct answer)
            //u = array of user answer words cleaned using custom clean function
            for (var z = 0; z < ca.length; z++) {
                caa = $.trim(ca[z]).split(" ");
                var pc = 0;
                for (var x = 0; x < caa.length; x++) {
                    for (var y = 0; y < u.length; y++) {
                        if (soundex(u[y]) != null && soundex(caa[x]) != null) {
                            if (soundex(u[y]) == soundex(caa[x])) {
                                pc = pc + 1;
                            }
                        }
                        else {
                            if (u[y].indexOf(caa[x]) > -1) {
                                pc = pc + 1;
                            }
                        }
                    }
                }
                if ((pc / caa.length) > 0.5) {
                    return true;
                }
            }
            return false;
        }
        
        // create object listing the SOUNDEX values for each letter
        // -1 indicates that the letter is not coded, but is used for coding
        //  0 indicates that the letter is omitted for modern census archives
        //                              but acts like -1 for older census archives
        //  1 is for BFPV
        //  2 is for CGJKQSXZ
        //  3 is for DT
        //  4 is for L
        //  5 is for MN my home state
        //  6 is for R
        function makesoundex() {
            this.a = -1
            this.b = 1
            this.c = 2
            this.d = 3
            this.e = -1
            this.f = 1
            this.g = 2
            this.h = 0
            this.i = -1
            this.j = 2
            this.k = 2
            this.l = 4
            this.m = 5
            this.n = 5
            this.o = -1
            this.p = 1
            this.q = 2
            this.r = 6
            this.s = 2
            this.t = 3
            this.u = -1
            this.v = 1
            this.w = 0
            this.x = 2
            this.y = -1
            this.z = 2
        }
        
        var sndx = new makesoundex()
        
        // check to see that the input is valid
        function isSurname(name) {
            if (name == "" || name == null) {
                return false
            } else {
                for (var i = 0; i < name.length; i++) {
                    var letter = name.charAt(i)
                    if (!(letter >= 'a' && letter <= 'z' || letter >= 'A' && letter <= 'Z')) {
                        return false
                    }
                }
            }
            return true
        }
        
        // Collapse out directly adjacent sounds
        // 1. Assume that surname.length>=1
        // 2. Assume that surname contains only lowercase letters
        function collapse(surname) {
            if (surname.length == 1) {
                return surname
            }
            var right = collapse(surname.substring(1, surname.length))
            if (sndx[surname.charAt(0)] == sndx[right.charAt(0)]) {
                return surname.charAt(0) + right.substring(1, right.length)
            }
            return surname.charAt(0) + right
        }
        
        // Collapse out directly adjacent sounds using the new National Archives method
        // 1. Assume that surname.length>=1
        // 2. Assume that surname contains only lowercase letters
        // 3. H and W are completely ignored
        function omit(surname) {
            if (surname.length == 1) {
                return surname
            }
            var right = omit(surname.substring(1, surname.length))
            if (!sndx[right.charAt(0)]) {
                return surname.charAt(0) + right.substring(1, right.length)
            }
            return surname.charAt(0) + right
        }
        
        // Output the coded sequence
        function output_sequence(seq) {
            var output = seq.charAt(0).toUpperCase() // Retain first letter
            output += "-" // Separate letter with a dash
            var stage2 = seq.substring(1, seq.length)
            var count = 0
            for (var i = 0; i < stage2.length && count < 3; i++) {
                if (sndx[stage2.charAt(i)] > 0) {
                    output += sndx[stage2.charAt(i)]
                    count++
                }
            }
            for (; count < 3; count++) {
                output += "0"
            }
            return output
        }
        
        // Compute the SOUNDEX code for the surname
        function soundex(value) {
            if (!isSurname(value)) {
                return null
            }
            var stage1 = collapse(value.toLowerCase())
            //form.result.value=output_sequence(stage1);
        
            var stage1 = omit(value.toLowerCase())
            var stage2 = collapse(stage1)
            return output_sequence(stage2);
        
        }
        
        function clean(u) {
            var u = u.replace(/\,/g, "");
            u = u.toLowerCase().split(" ");
            var cw = ["ARRAY OF WORDS TO BE EXCLUDED FROM COMPARISON"];
            var n = [];
            for (var y = 0; y < u.length; y++) {
                var test = false;
                for (var z = 0; z < cw.length; z++) {
                    if (u[y] != "" && u[y] != cw[z]) {
                        test = true;
                        break;
                    }
                }
                if (test) {
        //Don't use & or $ in comparison
                    var val = u[y].replace("$", "").replace("&", "");
                    n.push(val);
                }
            }
            return n;
        }

这是基于编辑距离的答案https://en.wikipedia.org/wiki/Levenshtein_distance https://en.wikipedia.org/wiki/Levenshtein_distance

function similarity(s1, s2) {
  var longer = s1;
  var shorter = s2;
  if (s1.length < s2.length) {
    longer = s2;
    shorter = s1;
  }
  var longerLength = longer.length;
  if (longerLength == 0) {
    return 1.0;
  }
  return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength);
}

用于计算编辑距离

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];
}

Usage

similarity('Stack Overflow','Stack Ovrflw')

返回 0.8571428571428571


您可以在下面使用它:

function checkSimilarity(){
  var str1 = document.getElementById("lhsInput").value;
  var str2 = document.getElementById("rhsInput").value;
  document.getElementById("output").innerHTML = similarity(str1, str2);
}

function similarity(s1, s2) {
      var longer = s1;
      var shorter = s2;
      if (s1.length < s2.length) {
        longer = s2;
        shorter = s1;
      }
      var longerLength = longer.length;
      if (longerLength == 0) {
        return 1.0;
      }
      return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength);
    }

    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];
    }
<div><label for="lhsInput">String 1:</label> <input type="text" id="lhsInput" oninput="checkSimilarity()" /></div>
<div><label for="rhsInput">String 2:</label> <input type="text" id="rhsInput" oninput="checkSimilarity()" /></div>
<div>Match: <span id="output">No Input</span></div>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

比较字符串 Javascript 返回可能的百分比 的相关文章

随机推荐

  • Web API 中的命名空间“System.Web”中不存在类型或命名空间“Http”

    我正在尝试按照此链接创建一个 Web API 我已经完全添加了它的显示方式this https www tutorialspoint com asp net mvc asp net mvc web api htm文章 但是添加控制器后 它给
  • 根据值向网格图添加边框

    我想知道你是否能帮我解决这个问题 我有一个由 0 和 1 组成的网格 如果它是 1 我想向绘图单元格区域添加边框颜色 我使用 imshow 生成根据值着色的网格 例如 a np random randint 2 size 10 10 im
  • Yarn 迷你集群容器日志目录不包含 syslog 文件

    我已经基于 CDH 5 1 0 的 hadoop 2 3 0 设置了带有 1 个节点管理器 4 个本地目录和 4 个日志目录等的 YARN MapReduce 迷你集群 它看起来或多或少起作用 我未能实现的是从容器进行系统日志记录 我看到容
  • 为什么 wget 输出到 stderr 而不是 stdout?

    经过 30 分钟徒劳尝试捕获输出后wget 我发现该程序写入stderr而不是stdout 在网络和堆栈溢出中搜索表明这是一个众所周知的事实 知道为什么会这样吗 这是众所周知的 因为它在manual http www gnu org sof
  • PHP 组合数组

    我如何组合这两个数组 如果数组有重复项 则只有一个使用 PHP 表示 Array 0 gt 18 1 gt 20 2 gt 28 3 gt 29 Array 0 gt 1 1 gt 8 2 gt 19 3 gt 22 4 gt 25 5 g
  • 如何对不描述函数的 N 个点进行插值

    Suppose i have n points also suppose that this points have an order and not necessary this points make a function I m wo
  • JavaFX ContextMenu 加速器从错误的选项卡触发

    我有一个TabPane有两个选项卡 每个选项卡都有一个TableView它有一个上下文菜单 这两个上下文菜单有重复的加速器 但我希望只有当前选定的选项卡才会响应 但发生的只是最后添加的Tab似乎得到了该事件 即使它没有被选择 下面是完整的示
  • 从子文件夹提供 React 应用程序时出错

    我正在尝试从子文件夹提供 React 应用程序 目前它是一个非常简单的 SPA 运行在根 URL 上 例如http 我的服务器 3000 http myserver 3000 并且我想从子文件夹中提供它 例如http myserver 30
  • 在仅包含值类型的自定义结构上使用 Marshal.SizeOf() 方法

    我创建了一个由两种值类型组成的简单结构 public struct Identifier public Guid ID get set public Byte RequestType get set 然后我打电话Marshal SizeOf
  • Django 中的 URL 正则表达式,具有有限的单词集

    给定以下 django URL conf 入口 url r P
  • 查找 2D 数组/矩阵中 k 个最高值的索引

    我有一个包含值的 2D 矩阵 我想找到前 5 个值的索引 例如对于 matrix 0 17542851 0 13199346 0 01579704 0 01429822 0 01302919 0 13279703 0 12444886 0
  • 自动完成jquery和SQL,ASP.NET

    我正在尝试使用 jquery 创建一个自动完成文本框 它将绑定到 SQL 数据库 我还想在页面上放置一个下拉列表 以便根据初始选择自动完成文本框将从不同的表中检索数据 这是一个 ASP NET 2 0 页面 背后的代码是 VB NET 我有
  • Swift:可选下标的可选链接

    我有一个let map String String and a let key String 最简洁的访问方式是什么map key 并取回String 如果我有一个key and None如果我没有 let value key flatMa
  • 如何在 ASP.NET MVC 控制器中使用 Automapper 配置

    我正在使用 AutoMapper 将模型转换为视图模型 我已经完成所有设置 测试和工作 作为参考 我的配置方法如下所示 public static MapperConfiguration Configure MapperConfigurat
  • Rails:更改生产数据库的最佳方法

    我需要对正在使用的生产数据库进行更改 只需添加几列即可 我已经通过迁移对开发数据库进行了更改 在保留现有数据且不会过多干扰操作的情况下更新生产数据库的最佳方法是什么 它是 MYSQL 我还需要向列添加数据以及现有记录 一列可以有默认值 它是
  • 如何在 docker 容器内使用 nginx 提供静态文件?

    因为我运行的是 Mac OSX 所以我使用 boot2docker 我不知道如何使用在 docker 容器内运行的 nginx 也包含静态资产 如我的 html 和 js 提供静态文件 我有四个 docker 容器正在与此一起旋转docke
  • 存储库模式实现

    似乎我找到的存储库模式的每个示例 其实现都在某种程度上有所不同 下面是我主要找到的两个例子 interface IProductRepository IQueryable
  • 由于 Xcode 11 中不再包含应用程序加载器,如何上传 IPA

    我有点害怕问这个问题 因为这个问题对我来说似乎很大 但我没有看到有人对此感到恐慌 我有点害怕听起来很疯狂 但我会坚持下去 正如我们可以在苹果的帖子中看到的提交更新 https developer apple com app store co
  • 如何在 Angular 2 中使用 Less?

    我想知道如何在我的 Angular 2 项目中添加更少的编译 因为每个组件都有自己的 css 文件 现在将是 less文件 我不确定如何使文件编译为 css 我也用谷歌搜索了这个问题 但没有找到任何解决我的问题的方法 EDIT为了让我的问题
  • 比较字符串 Javascript 返回可能的百分比

    我正在寻找一个 JavaScript 函数 它可以比较两个字符串并返回它们相似的可能性 我看过 soundex 但对于多单词字符串或非名称来说并不是很好 我正在寻找一个类似的函数 function compare strA strB com