字符串编辑距离
来源:互联网 发布:房屋装修平面设计软件 编辑:程序博客网 时间:2024/05/16 19:32
Levenshtein Distance (LD, 来文史特距离)也叫edit distance(编辑距离),它用来表示2个字符串的相似度,LD定义为需要最少多少步基本操作才能让2个字符串相等,基本操作包含3个:插入, 删除, 替换;比如,kiteen和sitting之间的距离可以这么计算:
1,kitten -- > sitten, 替换k为s;
2,sitten -- > sittin, 替换e为i;
3,sittin -- > sitting, 增加g;
所以,其LD为3。
设计状态d[m][n] = d(A[1..m], B[1..n]),易知:
d[0][0] = 0;
d[i][0] = i;
d[0][j] = j;
d[i][j] = min( d[i-1][j-1] + (If A[i]=B[j] Then 0 Else 1 End If), //修改一个字符
d[i-1][j] + 1, //插入一个字符
d[i][j-1] + 1 //删除一个字符
于是可以递推地填满一个 m * n 的矩阵,即得答案。
计算LD的算法表示为(C++代码):
int d[1010][1010];
int dist(string a, string b){
int m = a.size(), n = b.size(), i, j;
for(i = 0; i <= m; ++i) d[i][0] = i;
for(j = 0; j <= n; ++j) d[0][j] = j;
for (i = 1; i <= m; ++i){
for(j = 1; j <= n; ++j){
// -------------- a, b是从0开始计数的
d[i][j] = d[i-1][j-1] + (a[i-1]==b[j-1]?0:1); //修改一个字符
d[i][j] = min(d[i][j], d[i-1][j] + 1); //插入一个字符
d[i][j] = min(d[i][j], d[i][j-1] + 1); //删除一个字符
}
}
for (i = 0; i <= m; ++i){ //打印矩阵
for(j = 0; j <= n; ++j)
printf("%5d ", d[i][j]);
printf("\n");
}
return d[m][n];
}
这个算法其实就是一个矩阵的计算:
引用调用dist("abcdef", "acddaf")可以得到输出为:
0 1 2 3 4 5 6
1 0 1 2 3 4 5
2 1 1 2 3 4 5
3 2 1 2 3 4 5
4 3 2 1 2 3 4
5 4 3 2 2 3 4
6 5 4 3 3 3 3
1,kitten -- > sitten, 替换k为s;
2,sitten -- > sittin, 替换e为i;
3,sittin -- > sitting, 增加g;
所以,其LD为3。
设计状态d[m][n] = d(A[1..m], B[1..n]),易知:
d[0][0] = 0;
d[i][0] = i;
d[0][j] = j;
d[i][j] = min( d[i-1][j-1] + (If A[i]=B[j] Then 0 Else 1 End If), //修改一个字符
d[i-1][j] + 1, //插入一个字符
d[i][j-1] + 1 //删除一个字符
于是可以递推地填满一个 m * n 的矩阵,即得答案。
计算LD的算法表示为(C++代码):
int d[1010][1010];
int dist(string a, string b){
int m = a.size(), n = b.size(), i, j;
for(i = 0; i <= m; ++i) d[i][0] = i;
for(j = 0; j <= n; ++j) d[0][j] = j;
for (i = 1; i <= m; ++i){
for(j = 1; j <= n; ++j){
// -------------- a, b是从0开始计数的
d[i][j] = d[i-1][j-1] + (a[i-1]==b[j-1]?0:1); //修改一个字符
d[i][j] = min(d[i][j], d[i-1][j] + 1); //插入一个字符
d[i][j] = min(d[i][j], d[i][j-1] + 1); //删除一个字符
}
}
for (i = 0; i <= m; ++i){ //打印矩阵
for(j = 0; j <= n; ++j)
printf("%5d ", d[i][j]);
printf("\n");
}
return d[m][n];
}
这个算法其实就是一个矩阵的计算:
引用调用dist("abcdef", "acddaf")可以得到输出为:
0 1 2 3 4 5 6
1 0 1 2 3 4 5
2 1 1 2 3 4 5
3 2 1 2 3 4 5
4 3 2 1 2 3 4
5 4 3 2 2 3 4
6 5 4 3 3 3 3
最后的d[m][n]就是求得的答案。
递归算法如下:
#include <iostream>#include <cstring>using namespace std;int cal(char *s, char *t){ if(*s == 0x0) { if(*t != 0x0) return strlen(t); else return 0; } if(*t == 0x0) { if(*s != 0x0) return strlen(s); else return 0; } int s1t1=cal(s+1,t+1)+(s[0]==t[0]?0:1); int s0t1=cal(s,t+1)+1; int s1t0=cal(s+1,t)+1; return min(min(s1t1,s0t1),s1t1);}int main(){ cout<<cal("youare","areyou");}
贴一个优化空间复杂度为O(n)的代码(滚动数组):
int diff(char *a, char *b){ int *d[2], i, j; int m = strlen(a), n = strlen(b); d[0] = new int[n + 1]; d[1] = new int[n + 1]; int turn = 0, pre, t; for (i = 0; i <= n; ++i) d[turn][i] = i; for (i = 1; i <= m; ++i){ pre = turn; turn = (turn + 1) % 2; d[turn][0] = i; for(int p=0;p<=n;p++)printf("%d ",d[pre][p]);printf("\n"); for(j = 1; j <= n; ++j){ t = d[pre][j-1] + (a[i-1] == b[j-1] ? 0 : 1); t = min(t, d[pre][j] + 1); d[turn][j] = min(t, d[turn][j-1] + 1); } } for(int p=0;p<=n;p++)printf("%d ",d[turn][p]);printf("\n"); t = d[turn][n]; delete[] d[0]; delete[] d[1]; return t;}
0 0
- 字符串的编辑距离
- 字符串编辑距离查表法
- 求字符串编辑距离
- 字符串的编辑距离
- 字符串编辑距离
- 字符串编辑距离
- 1020 字符串编辑距离
- 字符串编辑距离
- 字符串编辑距离
- 字符串编辑距离
- 字符串编辑距离
- 求字符串编辑距离
- 字符串编辑距离
- 字符串编辑距离算法
- 编辑字符串距离
- 字符串编辑距离
- 字符串编辑距离
- 字符串编辑距离
- hdu 4502 吉哥系列故事——临时工计划
- 推荐html编辑器
- LeetCode Add Two Numbers
- 不实例化结构体获取结构体成员在结构体中的偏移量
- 使用Gitolite搭建Git服务器
- 字符串编辑距离
- non-native end of line sequence detected
- leetcode之Subsets
- 双向链表的C语言实现
- B - ZZY’s Dilemma
- 浏览器缓存机制
- dlutoj1247 hashtable数字查询优化
- Lesson_for_java_day13--java的常用类—StringBuffer、基本数据类型包装类、Date、Calender、Math、Runtime、System等
- HDOJ-2119 二分图最小覆盖=二分图最大匹配数