当我们使用 Google 等搜索功能时,会出现与搜索内容有关的候选项。使用 JavaScript 搜索字符串,通常会使用 indexOf 或者 search 函数,但是非常僵硬,只能搜索匹配特定词语。比如使用关键词 今天是星期几 想要检索 今天是星期五 这个内容,就无法实现,虽然它们只有很小的差别。

本文就来介绍一个有趣的算法 编辑距离(Levenshtein Distance),然后用它来实现一个简单的候选项推荐(模糊搜索)功能。

编辑距离(Levenshtein Distance)

简单的说,编辑距离就是把一个字符串修改变成另一个字符串的修改次数。如果修改的次数越小,我们可以简单的认为这两个字符串之间的关系越紧密。比如 今天是星期几 对于 今天是星期五明天是星期五比较,跟 今天是星期五 更加紧密一些,因为前者的编辑距离是 1,后者的编辑距离是 2。

更详细的百度百科已经说的很清楚了,这里不再赘述,主要给出 JavaScript 的实现方法:

按照自然语言表达的算法,我们先需要根据两个字符串的长度创建一个二维表:

function levenshtein(a, b) {var al = a.length + 1;var bl = b.length + 1;var result = [];var temp = 0;// 创建一个二维数组for (var i = 0; i < al; result[i] = [i++]) {}for (var i = 0; i < bl; result[0][i] = i++) {}
}

之后就需要遍历这个二位数组,按照如下的规则取得三个值的最小值:

  • 如果最上方的字符等于最左方的字符,则为左上方的数字。否则为左上方的数字 + 1。
  • 左方数字 + 1
  • 上方数字 + 1

需要判断两个值是否相等来决定左上方数字是否 + 1,所以引入 temp 变量。我们可以写出如下遍历代码:

for (i = 1; i < al; i++) {for (var j = 1; j < bl; j++) {// 判断最上方和最左方数字是否相等temp = a[i - 1] == b[j - 1] ? 0 : 1;// result[i - 1][j] + 1 左方数字// result[i][j - 1] + 1 上方数字// result[i - 1][j - 1] + temp 左上方数字result[i][j] = Math.min(result[i - 1][j] + 1, result[i][j - 1] + 1, result[i - 1][j - 1] + temp);}
}

最后将二维数组最后一个值返回,该值就是编辑距离:

return result[i-1][j-1];

这个函数就完成了:

function levenshtein(a, b) {var al = a.length + 1;var bl = b.length + 1;var result = [];var temp = 0;// 创建一个二维数组for (var i = 0; i < al; result[i] = [i++]) {}for (var i = 0; i < bl; result[0][i] = i++) {}        for (i = 1; i < al; i++) {for (var j = 1; j < bl; j++) {// 判断最上方和最左方数字是否相等temp = a[i - 1] == b[j - 1] ? 0 : 1;// result[i - 1][j] + 1 左方数字// result[i][j - 1] + 1 上方数字// result[i - 1][j - 1] + temp 左上方数字result[i][j] = Math.min(result[i - 1][j] + 1, result[i][j - 1] + 1, result[i - 1][j - 1] + temp);}}return result[i-1][j-1];}

实际应用

那么我们现在就来实现一个简单的搜索功能。

原文地址:http://www.yujiangshui.com/javascript-levenshtein-distance/

转载于:https://www.cnblogs.com/LoveOrHate/p/4487987.html

使用 JavaScript 实现简单候选项推荐功能(模糊搜索)【收藏】【转】相关推荐

  1. 用浏览器收藏夹的书签保存javascript的简单脚本

    用浏览器收藏夹的书签保存javascript的简单脚本 之前一直好奇别人是如何保存常用的javascipt脚本的 油猴脚本,需要考虑整体的运行方式,有时还得专门写个按钮,需要一定基础 记事本保存,用的 ...

  2. php简单实例,php实现推荐功能的简单实例

    php实现推荐功能的简单实例,魔法,标题,文章,简明扼要,数组 php实现推荐功能的简单实例 易采站长站,站长之家为您整理了php实现推荐功能的简单实例的相关内容. 利用similar_text将这些 ...

  3. 自己实现简单的AOP(三) 实现增强四项基本功能

    前面的两篇随笔,都是只是个铺垫,真正实现增强四项基本功能的重头戏,在本篇随笔中, 本文将通过AOP实现如下的四个基本功能: /// <para>1.自动管理数据库连接[可选]</pa ...

  4. GB/T 34590《道路车辆 功能安全 第1部分:术语》等12项推荐性国家标准及1项国家标准化指导性技术文件征求意见的函

    http://www.catarc.org.cn/StandardRevision/detail/2200.html 征求意见 <道路车辆 功能安全 第1部分:术语>等12项推荐性国家标准 ...

  5. html页面中加入评论功能,JavaScript实现简单评论功能

    本文实例为大家分享了JavaScript实现简单评论功能的具体代码,供大家参考,具体内容如下 body{ /*background-image: url(../img/91R58PIC3n2_1024 ...

  6. (强烈推荐)免费ERP-2BizBox为全球制造业企业提供的一款简单易用、功能齐全的ERP软件

    (强烈推荐)免费ERP-2BizBox为全球制造业企业提供的一款简单易用.功能齐全的ERP软件 2BizBox是为全球制造业企业提供的一款简单易用.功能齐全的ERP软件. 功能完善 2BizBox是针 ...

  7. 【JavaScript练习】用户输入任意两个数字的任意算数运算(简单的计算器小功能)并弹出运算后的结果。

    [JavaScript练习]用户输入任意两个数字的任意算数运算(简单的计算器小功能)并弹出运算后的结果. <!DOCTYPE html> <html lang="en&qu ...

  8. JavaScript css3模拟简单的视频弹幕功能

    最近相对比较空闲,想写一些东西写着玩.就尝试写了一个demo模拟了最简单的视频弹幕功能~~. 思路: 设置一个<div>和所播放的video的大小一致,把这个div标签蒙在video上面用 ...

  9. php 单点登录实现代码,PHP简单实现单点登录功能示例

    1.准备两个虚拟域名 127.0.0.1  www.openpoor.com 127.0.0.1  www.myspace.com 2.在openpoor的根目录下创建以下文件 index.PHP 1 ...

最新文章

  1. 北大韦神透露现状:自己课讲得不太好,中期学生退课后就剩下5、6个人...
  2. Premiere Pro CC2015软件安装教程
  3. 乐享计算机会计学院,EMBA
  4. 关于网站URL转码的问题
  5. NSDate 类的总结,全面基础
  6. 【光说不练假把式】今天说一说Kubernetes 在有赞的实践
  7. 云栖大会 | 释放计算弹性,阿里云做了很多
  8. QObject::connect: No such signal QGraphicsView::mouseMovePoint(QPoint) in ***
  9. SQLServer2008数据库还原失败 恢复失败
  10. Libfetion在Ubuntu下的中文输出了局
  11. 计算机存储换算 2GB等于多少MB,一gb等于多少mb 1gb等于多少mb?存储单位的含义和换算【详解】...
  12. 微信语音技术原理_玩人工智能的你必须知道的语音识别技术原理
  13. colab使用入门(1)-安装库,保存/加载笔记本
  14. 3D打印Arduino 四轴飞行器
  15. PHP--extract 从数组中将变量导入到当前的符号表
  16. 怎么看产品的引流关键词?淘宝如何找到自己宝贝的引流关键词?
  17. 基于python的批量网页爬虫
  18. 计量经济学之时间序列的平稳性、单位根检验、协整检验、时间序列数据的一般处理流程
  19. 打造云原生大型分布式监控系统(三): Thanos 部署与实践
  20. Xadmin文档(二)

热门文章

  1. 删除一行下方单元格上移_快速删除Excel工作表多余空单元格
  2. 十六、PHP框架Laravel学习笔记——构造器的增删改
  3. 十二、一篇文章帮助你快速读懂MySQL索引(B树、B+树详解)
  4. LeetCode 1007. 行相等的最少多米诺旋转
  5. LeetCode 308. 二维区域和检索 - 可变(前缀和)
  6. LeetCode 793. 阶乘函数后K个零(二分查找)
  7. 怎样切换git账号密码错误_git中多账号切换问题的解决方案(转)
  8. fileinputstream_从Java中的FileInputStream读取字节
  9. python 类继承 父类初始化_python之子类继承父类时进行初始化的一些问题
  10. python去重复元素_Python实现去除列表中重复元素的方法总结【7种方法】