一个快速、高效的Levenshtein算法实现
转自:http://www.cnblogs.com/ymind/archive/2012/03/27/fast-memory-efficient-Levenshtein-algorithm.html
Levenshtein算法,用于计算两个字符串之间的Levenshtein距离。而Levenshtein距离又称为编辑距离,是指两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
概述
Levenshtein距离用来描述两个字符串之间的差异。我在一个网络爬虫程序里面使用这个算法来比较两个网页之间的版本,如果网页的内容有足够多的变动,我便将它更新到我的数据库。
说明
原来的算法是创建一个大小为StrLen1*StrLen2的矩阵。如果所有字符串加起来是1000个字符那么长的话,那么这个矩阵就会是1M;如果字符串是10000个字符,那么矩阵就是100M。如果元素都是整数(这里是指数字,Int32)的话,那么矩阵就会是4*100M == 400MB这么大,唉……
现在的算法版本只使用2*StrLen个元素,这使得后面给出的例子成为2*10,000*4 = 80 KB。其结果是,不但内存占用更少,而且速度也变快了!因为这使得内存分配只需要很少的时间来完成。当两个字符串的长度都是1k左右时,新算法的效率是旧算法的两倍!
示例
原来的版本将会创建一个矩阵[6+1, 5+1],而我的新算法将会创建两个向量[6+1](黄色元素)。在这两个算法版本中,字符串的顺序是无关紧要、无所谓的,也就是说,它也可以是矩阵[5+1, 6+1]和两个向量[5+1]。
新的算法
步骤
| 步骤 | 说明 |
|---|---|
| 1 | 设置n为字符串s的长度。("GUMBO") 设置m为字符串t的长度。("GAMBOL") 如果n等于0,返回m并退出。 如果m等于0,返回n并退出。 构造两个向量v0[m+1] 和v1[m+1],串联0..m之间所有的元素。 |
| 2 | 初始化 v0 to 0..m。 |
| 3 | 检查 s (i from 1 to n) 中的每个字符。 |
| 4 | 检查 t (j from 1 to m) 中的每个字符 |
| 5 | 如果 s[i] 等于 t[j],则编辑代价为 0; 如果 s[i] 不等于 t[j],则编辑代价为1。 |
| 6 | 设置单元v1[j]为下面的最小值之一: a、紧邻该单元上方+1:v1[j-1] + 1 b、紧邻该单元左侧+1:v0[j] + 1 c、该单元对角线上方和左侧+cost:v0[j-1] + cost |
| 7 | 在完成迭代 (3, 4, 5, 6) 之后,v1[m]便是编辑距离的值。 |
本小节将演示如何计算"GUMBO"和"GAMBOL"两个字符串的Levenshtein距离。
步骤1、2
| v0 | v1 | |||||
| G | U | M | B | O | ||
| 0 | 1 | 2 | 3 | 4 | 5 | |
| G | 1 | |||||
| A | 2 | |||||
| M | 3 | |||||
| B | 4 | |||||
| O | 5 | |||||
| L | 6 |
步骤3-6,当 i = 1
| v0 | v1 | |||||
| G | U | M | B | O | ||
| 0 | 1 | 2 | 3 | 4 | 5 | |
| G | 1 | 0 | ||||
| A | 2 | 1 | ||||
| M | 3 | 2 | ||||
| B | 4 | 3 | ||||
| O | 5 | 4 | ||||
| L | 6 | 5 |
步骤3-6,当 i = 2
| v0 | v1 | |||||
| G | U | M | B | O | ||
| 0 | 1 | 2 | 3 | 4 | 5 | |
| G | 1 | 0 | 1 | |||
| A | 2 | 1 | 1 | |||
| M | 3 | 2 | 2 | |||
| B | 4 | 3 | 3 | |||
| O | 5 | 4 | 4 | |||
| L | 6 | 5 | 5 |
步骤3-6,当 i = 3
| v0 | v1 | |||||
| G | U | M | B | O | ||
| 0 | 1 | 2 | 3 | 4 | 5 | |
| G | 1 | 0 | 1 | 2 | ||
| A | 2 | 1 | 1 | 2 | ||
| M | 3 | 2 | 2 | 1 | ||
| B | 4 | 3 | 3 | 2 | ||
| O | 5 | 4 | 4 | 3 | ||
| L | 6 | 5 | 5 | 4 |
步骤3-6,当 i = 4
| v0 | v1 | |||||
| G | U | M | B | O | ||
| 0 | 1 | 2 | 3 | 4 | 5 | |
| G | 1 | 0 | 1 | 2 | 3 | |
| A | 2 | 1 | 1 | 2 | 3 | |
| M | 3 | 2 | 2 | 1 | 2 | |
| B | 4 | 3 | 3 | 2 | 1 | |
| O | 5 | 4 | 4 | 3 | 2 | |
| L | 6 | 5 | 5 | 4 | 3 |
步骤3-6,当 i = 5
| v0 | v1 | |||||
| G | U | M | B | O | ||
| 0 | 1 | 2 | 3 | 4 | 5 | |
| G | 1 | 0 | 1 | 2 | 3 | 4 |
| A | 2 | 1 | 1 | 2 | 3 | 4 |
| M | 3 | 2 | 2 | 1 | 2 | 3 |
| B | 4 | 3 | 3 | 2 | 1 | 2 |
| O | 5 | 4 | 4 | 3 | 2 | 1 |
| L | 6 | 5 | 5 | 4 | 3 | 2 |
步骤7
编辑距离就是矩阵右下角的值,v1[m] == 2。由"GUMBO"变换为"GAMBOL"的过程对于我来说是很只管的,即通过将"A"替换为"U",并在末尾追加"L"这样子(实际上替换的过程是由移除和插入两个操作组合而成的)。
改良
如果您确信你的字符串永远不会超过2^16(65536)个字符,那么你可以使用ushort来表示而不是int,如果字符串少于2^8个,还可以使用byte。我觉得这个算法用非托管代码实现的话可能会更快,但我没有试过。
参考文献
下载代码请前往原文:http://www.codeproject.com/Articles/13525/Fast-memory-efficient-Levenshtein-algorithm
一个快速、高效的Levenshtein算法实现的更多相关文章
- 一个快速、高效的Levenshtein算法实现——代码实现
在网上看到一篇博客讲解Levenshtein的计算,大部分内容都挺好的,只是在一些细节上不够好,看了很长时间才明白.我对其中的算法描述做了一个简单的修改.原文的链接是:一个快速.高效的Levensht ...
- 如何快速高效地完成一个Android项目?
本文的内容有别于之前文章中纯技术的探讨,会从业务逻辑.技术.团队和方法论的角度探讨如何快速高效地完成一个Android项目.当然,快速高效是有前提的,第一,本文依然是从研发的角度来谈如何把控项目的,而 ...
- 【译】快速高效学习Java编程在线资源Top 20
想要加强你的编程能力吗?想要提升你的 Java 编程技巧和效率吗? 不用担心.本文将会提供快速高效学习 Java 编程的 50 多个网站资源: 开始探索吧: 1.MKyong:许多开发者在这里可以找到 ...
- 软阈值迭代算法(ISTA)和快速软阈值迭代算法(FISTA)
缺月挂疏桐,漏断人初静. 谁见幽人独往来,缥缈孤鸿影. 惊起却回头,有恨无人省. 拣尽寒枝不肯栖,寂寞沙洲冷.---- 苏轼 更多精彩内容请关注微信公众号 "优化与算法" ISTA ...
- 快速高效学习Java编程在线资源Top 20(转载)
想要加强你的编程能力吗?想要提升你的 Java 编程技巧和效率吗? 不用担心.本文将会提供快速高效学习 Java 编程的 50 多个网站资源: 开始探索吧: 1.MKyong:许多开发者在这里可以找到 ...
- 【转】C语言快速幂取模算法小结
(转自:http://www.jb51.net/article/54947.htm) 本文实例汇总了C语言实现的快速幂取模算法,是比较常见的算法.分享给大家供大家参考之用.具体如下: 首先,所谓的快速 ...
- FoxOne---一个快速高效的BS框架--WEB控件属性编辑器
FoxOne---一个快速高效的BS框架--(1) FoxOne---一个快速高效的BS框架--(2) FoxOne---一个快速高效的BS框架--(3) FoxOne---一个快速高效的BS框架-- ...
- FoxOne---一个快速高效的BS框架--(4)
FoxOne---一个快速高效的BS框架--(1) FoxOne---一个快速高效的BS框架--(2) FoxOne---一个快速高效的BS框架--(3) FoxOne---一个快速高效的BS框架-- ...
- FoxOne---一个快速高效的BS框架--(2)
FoxOne---一个快速高效的BS框架--(1) FoxOne---一个快速高效的BS框架--(2) FoxOne---一个快速高效的BS框架--(3) FoxOne---一个快速高效的BS框架-- ...
随机推荐
- Redis配置文件主要功能说明
原文地址:http://blog.csdn.net/htofly/article/details/7686436 配置文件参数说明: 1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改 ...
- BurpSuite之SQL Injection
BurpSuite之SQL Injection[平台]:mutillidae[工具]BurpSuite 1.4.07 + FireFox1:安装配置mutillidae如果遇到问题,开下面的帖子.ht ...
- 清空file input框
测试环境:OS --> winXPBrowsers --> IE6+, FF 3.0.11, FF 3.5, Opera 9.64, Opera 10 beta 2, Safari 4, ...
- IE input file隐藏不能上传文件解决方法
当大神们都在探讨更深层次的问题时,我还在这里转载发些肤浅的问题解决方案.罢了,为了和我一样笨的后来人. 问题: 上传文件时,用<input type="file" /> ...
- 【原创】ui.router源码解析
Angular系列文章之angular路由 路由(route),几乎所有的MVC(VM)框架都应该具有的特性,因为它是前端构建单页面应用(SPA)必不可少的组成部分. 那么,对于angular而言,它 ...
- ASP.NET 生成二维码(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
最近做项目遇到生成二维码的问题,发现网上用的最多的是ThoughtWorks.QRCode和QrCode.Net两种方式.访问官网看着例子写了两个Demo,使用过程中发现两个都挺好用的,Thought ...
- xxxx is not translated in zh-rCN, zh-rTW
1.异常提示: "image_content" is not translated in zh-rCN, zh-rTW 2.错误原因: 根据报错提示,是说我没有对string文件做 ...
- java常见异常集锦
1. java.lang.nullpointerexception 这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存在的对 ...
- HDU3345广搜 (P,E,T,#)
War chess is hh's favorite game:In this game, there is an N * M battle map, and every player has his ...
- C/C++语法知识:typedef struct 用法详解
第一篇:typedef struct与struct的区别 1. 基本解释 typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(int,char等)和自定 ...