使用 JavaScript 实现简单候选项推荐功能(模糊搜索)

转载 2016年05月30日 12:05:55

http://yujiangshui.com/javascript-levenshtein-distance/

当我们使用 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];
	
}

实际应用

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

大体思路就是将数据与要搜索的字符串计算编辑距离,然后进行排序,将编辑距离小的放在上面显示。具体 Demo 做在 jsfiddle 上面了:

也可以点击这里查看。

使用起来是有点效果的,比如:

但是也有很大的偏差,比如要搜索的关键词和相似结果编辑距离太大,超过了同等长度的不同字符,这时候就会出现错误的推荐:

如果数据足够多,各种情况都具备,那么推荐准确的可能性更大些。如果要改善这个功能,可能需要结合中文分词对关键词进行匹配综合等等,超出本文范畴这里不再赘述。

如果你有更好的方法和思路,欢迎留言讨论。


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

http://www.cnblogs.com/LoveOrHate/p/4487987.html 当我们使用 Google 等搜索功能时,会出现与搜索内容有关的候选项。使用 JavaScri...
  • SalmonellaVaccine
  • SalmonellaVaccine
  • 2016年06月06日 14:53
  • 212

实现类似百度搜索框中模糊提示功能

通常,在我们使用百度的时候,在输入框中输入某一个字段的时候,就可以查询到相关的信息。类似的功能可以通过JS的框架来实现(显然不会像百度那么强大)。jquery提供了一种扩展插件。可以实现获取文本框内容...
  • qq_27603235
  • qq_27603235
  • 2016年07月14日 12:48
  • 3618

用Vue.js实现一个简单的搜索框

用简单的vuejs2.0的知识实现简单的搜索框。 两个组件,一个组件是logo部分的,一个是搜索框部分的。...
  • weixin_35987513
  • weixin_35987513
  • 2016年11月23日 18:37
  • 13488

Axure的简单操作(模糊搜索)

Axure中的模糊搜索
  • sunshine_hl
  • sunshine_hl
  • 2015年07月23日 23:27
  • 4705

vue vue搜索 vue模糊搜索

1、使用vue来实现一般搜索 {{item1.name}} ...
  • zhumizhumi
  • zhumizhumi
  • 2017年12月25日 13:48
  • 167

Java中文键树的一种实现(附带模糊查询功能)

首先在文章的开头声明一下哈,本文只是介绍一种Java蛮力键树的实现,并没有什么高深的数据结构,所以数据量不超过百万字符的可以参考,数据量太大的另请高明吧。另外,后面的键树代码实际上不仅适用于中文存储和...
  • yuhk231
  • yuhk231
  • 2016年05月30日 17:43
  • 2674

Ajax 模糊查询的简单实现

类似于百度的搜索引擎模糊查询功能,不过百度的模糊查询功能更强大,这里简单实现下. 要实现模糊查询,首先要做的就是把SQL写好。话不多少,直接贴代码了! JSP页面: ...
  • yulei_qq
  • yulei_qq
  • 2014年01月03日 11:03
  • 9318

Servlet+ajax实现模糊搜索

首先模糊搜索,我们都很常见,比如百度搜索等等,当我们在输入框输入一定的字符,输入框下面就会智能提示一些相关联的数据,而这种情况下,我们的浏览器确没有刷新,这就用到了javaweb中ajax局部刷新。那...
  • y532798113
  • y532798113
  • 2017年02月27日 20:02
  • 368

使用textField实现搜索功能

作为一个编程小白,这个功能纠结了我几天,边完成公司交给我的任务边想如何实现搜索的思路,终于,要放假了,也就想出来了 还有以后在开发过程中如果没有其他特殊的要求,真的不需要用textField...
  • Mz_jiujiuguiyi
  • Mz_jiujiuguiyi
  • 2016年12月09日 11:40
  • 1702

angularjs的过滤器实现搜索与排序

angularjs的过滤器实现搜索与排序 利用angularjs实现动态的插入以及利用过滤器进行数据的搜索以及排序. Document 姓名 年龄 ...
  • b1244154318
  • b1244154318
  • 2016年09月19日 22:14
  • 5864
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用 JavaScript 实现简单候选项推荐功能(模糊搜索)
举报原因:
原因补充:

(最多只允许输入30个字)