课设代码位置https://github.com/treeandgrass/Algorithm-Course-Design
最小编辑距离
1.介绍
最小编辑距离由Vladimir Levenshtein在1965年提出,在信息理论和计算机科学中常被是用来计算两个不同字符序列中一个序列变为另一个序列所需的最少编辑操作次数。
2.算法实现
2.1算法分析
编辑距离是一种衡量两个相似字符串相似性的度量方法。距离越大相似度越小。具体地,两个字符串的编辑距离是其中一个字符串要变换为另一个字符串所需要的最小编辑次数。其中编辑操作包含3种:增加一个字符,删除一个字符,更改一个字符。假设存在两个字符串S1,S2,设函数F(S1,S2,i,j)为字符串S1的前i个字符和S2的前j个字符的编辑距离,S1[i],S2[j]的可能相等或不等。假设s1[i]等于s[j],则存在如下表达式:
F(S1,S2,i,j)=Min(F(S1,S2,i-1,j-1),F(S1,S2,i,j-1),F(S1,S2,i-1,j))
假设S1[i]不等于S2[j],则可以得到如下表达式:
F(S1,S2,i,j)=Min(F(S1,S2,i-1,j-1)+1,F(S1,S2,i,j-1),F(S1,S2,i-1,j))
综上所述可以得到如下公式:
2.2伪代码
2.3举例说明
假设存在如下两个字符串NOITNETNI、EXECUTION,需要计算它们的编辑距离。我们创建一个表,用填表的方式来进行计算。
初始化表
使用公式来填表的过程
最后完成的过程
2.4代码实现
提供了三种代码实现的方式
package two.two.one;
/**
* 编辑距离
* @author ym
*
*/
public class LevenshteinDistance {
/**
* 返回数组中的最小值
*
* @param arr
* @return
*/
public int min(int[]arr){
int min = Integer.MAX_VALUE;
for(int i=0;i<arr.length;i++){
if(arr[i]<min){
min=arr[i];
}
}
return min;
}
/**
*
* 以递归的方式计算编辑距离
*
*
* @param source
* @param target
* @return
*/
public int LevenshteinDistance1(Stringsource,Stringtarget,int i,int j){
if(i<1){
return j;
}
else if(j<1){
return i;
}
else{
int cost = 0;
if(source.charAt(i-1)!=target.charAt(j-1)){
cost=1;
}
int[] arr={LevenshteinDistance1(source,target,i-1,j)+1,
LevenshteinDistance1(source, target, i, j-1)+1,
LevenshteinDistance1(source, target, i-1, j-1)+cost};
return min(arr);
}
}
/**
* 矩阵存储方式计算
*
* @param source
* @param target
* @return
*/
public int LevenshteinDistance2(Stringsource,Stringtarget){
int[][] matrix = new int[source.length()][target.length()];
for(int i=0;i<source.length();i++){
matrix[i][0]=i+1;
}
for(int j=0;j<target.length();j++){
matrix[0][j]=j+1;
}
for(int i=1;i<source.length();i++){
for(int j=1;j<target.length();j++){
int cost=0;
if(target.charAt(j)!=source.charAt(j)){
cost=1;
}
int[] arr={matrix[i-1][j]+1,matrix[i][j-1]+1,matrix[i-1][j-1]+cost};
matrix[i][j]=min(arr);
}
}
return matrix[source.length()-1][target.length()-1];
}
/**
*
* 方式三,以数组的方式
* 来计算编辑距离
*
*
* @param source
* @param target
* @return
*/
public int LevenshteinDistance3(Stringsource,Stringtarget){
int len=target.length()+1;
int[] arr1= new int[len];
int[] arr2 = new int[len];
for(int i=0;i<source.length();i++){
arr2[0]=i;
for(int j=0;j<target.length();j++){
int cost=0;
if(source.charAt(i)!=target.charAt(j)){
cost=1;
}
int[] arr={arr1[j+1]+1,arr1[j]+cost,arr2[j]+1};
arr2[j+1]=min(arr);
}
//更新arr1
for(int k=0;k<len;k++){
arr1[k]=arr2[k];
}
}
return arr2[len-1];
}
public static void main(String[]args) {
LevenshteinDistance LD = new LevenshteinDistance();
//测试用例1 (sitting,kitten)
System.out.println(LD.LevenshteinDistance1("sitting","kitten",7, 6));
System.out.println(LD.LevenshteinDistance2("sitting","kitten"));
System.out.println(LD.LevenshteinDistance3("sitting","kitten"));
//测试用例二(httpuu,httupu)
System.out.println(LD.LevenshteinDistance1("httpuu","httupu",6, 5));
System.out.println(LD.LevenshteinDistance2("httpuu","httupu"));
System.out.println(LD.LevenshteinDistance3("httpuu","httupu"));
}
}
3.应用介绍
3.1最小编辑距离实际应用
最小编辑距离用来检查两个字符串的编辑距离,则可以使用编辑距离来判断两个字符串的相似程度。在程序系统设计中用来检查用户输入是否合法,在自然语言处理中,常用该方法来计算两段文本的相似程度。
3.2使用建议
在实际应用中,最小编辑距离常用来评价相似度,但是需要进行恰当的场景选择,编辑距离并不能适合所有相似度的评价,对于实际问题,应用编辑距离评价相似度可能是无用的。可以选择其它计算相似度的方法,比如在特征工程中,计算两个对象的相似度可以通过使用余弦公式来计算特征向量之间的相似度。
4.总结
最小编辑距离在很多的场景下都能有不错的表现,并且时间效率不错,并且实现比较简单,如果可以使用最小编辑距离能解决的问题,可以直接使用最小编辑距离算法计算相似度。
备注:一次课设作业