#include <string.h>
#include <stdlib.h>
//!注意 将min嵌入f会提高速度
int min(int a,int b,int c)
{
int min = a<b?a:b;
min = min<c?min:c;
return min;
}
//字符串编辑距离
//递归版
int d(const char * a,const char * b, int ap,int bp){
int n = strlen(a)-ap;
int m = strlen(b)-bp;
if(n==0)return m;
if(m==0)return n;
if(*(a+ap) == *(b+bp)){
return d(a,b,ap+1,bp+1);
}
else{
return min(d(a,b,ap+1,bp+1),d(a,b,ap+1,bp),d(a,b,ap,bp+1))+1;
}
}
///
//动态规划版(相对递归版,记录了重叠子问题的解)
int d_pro(const char * a,const char *b){
int i,j,k=0;
//初始化计数空间
int n = strlen(a);
int m = strlen(b);
int **c = new int * [n+1];//c是从0计算到n,n+1位
for(i=0;i<n+1;i++){
c[i]=new int [m+1];
}
//初值
for(j=1;j<n+1;j++){
for(k=1;k<m+1;k++){
c[j][k]=9999999;//初始距离都很大
}
}
//起始点
for(k=0;k<m+1;k++){
c[0][k]=k;
}
for(j=0;j<n+1;j++){
c[j][0]=j;
}
//调用 二维数组推算
for(j=1;j<n+1;j++){
for(k=1;k<m+1;k++){
if(a[j-1]==b[k-1]){
c[j][k]=c[j-1][k-1];
}else{
c[j][k]=min(c[j-1][k],c[j][k-1],c[j-1][k-1])+1;
}
}
}
int des=c[n][m];
//销毁内存
for (i=0;i<n;i++)
{
delete[] c[i];
}
delete[] c;
return des;
}
理论见之前笔记。
实例1:两个字符串编辑距离d,相似度 1/(d+1)
d为使用操作步骤最少的决策。
操作包括:修改一个字符,增加一个字符,删除一个字符
递归法时间复杂度高,动态规划用时间换空间,O(n*m)即可
说说动态规划 二维表的计算。
首先考虑边界条件(往往也是二维表的边界),然后状态转移,从而逐步填充二维表。
c (n+1,m+1)
c 0 1 2 ... m+1
0 0 1 2 .....m+1
1 1
2 2
3 3
... ...
n +1 n+1
c[i][j] 表示字符串A后I个字符组成的字符串与B后面J个字符组成的字符串的编辑距离。 (这里多加了一维)
那么c[0][0]代表两个空字符串的编辑距离(0)
c[0][k] 为k
c[j][0] 为j
C[x][y]= C[x-1][y-1] a[x-1]==b[y-1]
C[x][y]= min(C[x-1][y] ,C[x][y-1] ,C[x-1][y-1])+1
即可推算