【转】编辑距离
来源:互联网 发布:l2tp客户端软件 编辑:程序博客网 时间:2024/05/29 08:30
Levenshtein Distance, in Three Flavors
by Michael Gilleland
The purpose of this short essay is to describe the Levenshtein distance algorithm and show how it can be implemented in three different programming languages.
What is Levenshtein Distance?
Demonstration
The Algorithm
Source Code, in Three Flavors
References
Other Flavors
What is Levenshtein Distance?
Levenshtein distance (LD) is a measure of the similarity between two strings, which we will refer to as the source string (s) and the target string (t). The distance is the number of deletions, insertions, or substitutions required to transform s into t. For example,
- If s is "test" and t is "test", then LD(s,t) = 0, because no transformations are needed. The strings are already identical.
- If s is "test" and t is "tent", then LD(s,t) = 1, because one substitution (change "s" to "n") is sufficient to transform s into t.
The greater the Levenshtein distance, the more different the strings are.
Levenshtein distance is named after the Russian scientist Vladimir Levenshtein, who devised the algorithm in 1965. If you can't spell or pronounce Levenshtein, the metric is also sometimes called edit distance.
The Levenshtein distance algorithm has been used in:
- Spell checking
- Speech recognition
- DNA analysis
- Plagiarism detection
Demonstration
The following simple Java applet allows you to experiment with different strings and compute their Levenshtein distance:
The Algorithm
Steps
Step Description 1Set n to be the length of s.Set m to be the length of t.
If n = 0, return m and exit.
If m = 0, return n and exit.
Construct a matrix containing 0..m rows and 0..n columns.2Initialize the first row to 0..n.
Initialize the first column to 0..m.
3Examine each character of s (i from 1 to n).4Examine each character of t (j from 1 to m).5If s[i] equals t[j], the cost is 0.
If s[i] doesn't equal t[j], the cost is 1.6Set cell d[i,j] of the matrix equal to the minimum of:
a. The cell immediately above plus 1: d[i-1,j] + 1.
b. The cell immediately to the left plus 1: d[i,j-1] + 1.
c. The cell diagonally above and to the left plus the cost: d[i-1,j-1] + cost.
7After the iteration steps (3, 4, 5, 6) are complete, the distance is found in cell d[n,m].
Example
This section shows how the Levenshtein distance is computed when the source string is "GUMBO" and the target string is "GAMBOL".
Steps 1 and 2
GUMBO 012345G1 A2 M3 B4 O5 L6Steps 3 to 6 When i = 1
GUMBO 012345G10 A21 M32 B43 O54 L65Steps 3 to 6 When i = 2
GUMBO 012345G101 A211 M322 B433 O544 L655Steps 3 to 6 When i = 3
GUMBO 012345G1012 A2112 M3221 B4332 O5443 L6554Steps 3 to 6 When i = 4
GUMBO 012345G10123 A21123 M32212 B43321 O54432 L65543Steps 3 to 6 When i = 5
GUMBO 012345G101234A211234M322123B433212O544321L655432Step 7
The distance is in the lower right hand corner of the matrix, i.e. 2. This corresponds to our intuitive realization that "GUMBO" can be transformed into "GAMBOL" by substituting "A" for "U" and adding "L" (one substitution and 1 insertion = 2 changes).
Source Code, in Three Flavors
Religious wars often flare up whenever engineers discuss differences between programming languages. A typical assertion is Allen Holub's claim in a JavaWorld article (July 1999): "Visual Basic, for example, isn't in the least bit object-oriented. Neither is Microsoft Foundation Classes (MFC) or most of the other Microsoft technology that claims to be object-oriented."
A salvo from a different direction is Simson Garfinkels's article in Salon (Jan. 8, 2001) entitled "Java: Slow, ugly and irrelevant", which opens with the unequivocal words "I hate Java".
We prefer to take a neutral stance in these religious wars. As a practical matter, if a problem can be solved in one programming language, you can usually solve it in another as well. A good programmer is able to move from one language to another with relative ease, and learning a completely new language should not present any major difficulties, either. A programming language is a means to an end, not an end in itself.
As a modest illustration of this principle of neutrality, we present source code which implements the Levenshtein distance algorithm in the following programming languages:
- Java
- C++
- Visual Basic
These three implementations are hereby placed in the public domain and are free for anyone to use.
Java
C++
In C++, the size of an array must be a constant, and this code fragment causes an error at compile time:
int sz = 5; int arr[sz];
This limitation makes the following C++ code slightly more complicated than it would be if the matrix could simply be declared as a two-dimensional array, with a size determined at run-time.
In C++ it's more idiomatic to use the System Template Library's vector class, as Anders Sewerin Johansen has done in an alternative C++ implementation.
Here is the definition of the class (distance.h):
Visual Basic
References
Other discussions of Levenshtein distance are:
- Lloyd Allison, Dynamic Programming Algorithm (DPA) for Edit-Distance
- Alex Bogomolny, Distance Between Strings
- Thierry Lecroq, Levenshtein Distance
Other Flavors
The following people have kindly consented to make their implementations of the Levenshtein Distance Algorithm in various languages available here:
- Eli Bendersky has written an implementation in Perl.
- Barbara Boehmer has written an implementation in Oracle PL/SQL.
- Rick Bourner has written an implementation in Objective-C.
- Chas Emerick has written an implementation in Java, which avoids an OutOfMemoryError which can occur when my Java implementation is used with very large strings.
- Joseph Gama has written an implementation in TSQL, as part of a package of TSQL functions at Planet Source Code.
- Anders Sewerin Johansen has written an implementation in C++, which is more elegant, better optimized, and more in the spirit of C++ than mine.
- Lasse Johansen has written an implementation in C#.
- Adam Lindberg and Fredrik Svensson have written an implementation in Erlang.
- Alvaro Jeria Madariaga has written an implementation in Delphi.
- Lorenzo Seidenari has written an implementation in C, and Lars Rustemeier has provided a Scheme wrapper for this C implementation as part of Eggs Unlimited, a library of extensions to the Chicken Scheme system.
- Steve Southwell has written an implementation in Progress 4gl.
- Lukasz Stilger has written an implementation in JavaScript which illustrates the algorithm in operation (well worth seeing). Note that "wyraz" is Polish for "word". A separate page with the source code as text is here.
- Jorge Mas Trullenque points out that "the calculation needs O(n) memory, so using a two-dimensional matrix in a practical implementation is wasteful." He has written an implementation in Perl that uses only one one-dimensional vector.
- Joerg F. Wittenberger has written an implementation in Rscheme.
Other implementations outside these pages include:
- An Emacs Lisp implementation by Art Taylor.
- A Python implementation by Magnus Lie Hetland.
- A Tcl implementation by Richard Suchenwirth (thanks to Stefan Seidler for pointing this out).
- A PHP implementation (thanks to Dan Tripp for pointing this out).
- A Scheme implementation by Neil Van Dyke.
转自:http://www.merriampark.com/ld.htm
- 【转】编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 编辑距离
- 【转】高级动态规划
- 熊猫烧香制造者李俊出狱以后的六种出路
- SIP消息头域的说明
- 在Fedora 12上安装谷歌应用程序
- 九 java面向对象程序设计(this关键字)
- 【转】编辑距离
- 十 java面向对象程序设计(static关键字)
- Silverlight图像处理相关
- JPA引进之路
- 字符编码详解及由来(UNICODE,UTF-8,GBK)[转帖]
- 12.28
- 开发员网站
- 在应用程序或全局主题目录中无法找到主题
- Winforms: 在Vista中基于.NET 2.0的GIF动画显示问题