暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

最小编辑距离算法及C和Python代码实现

语和言 2018-10-19
716

一、什么是最小编辑距离


通过三种基本的字符操作(插入、删除、替换)将一个字符串s变为另一个字符串t所需要的最少操作次数称为字符串s和t的最小编辑距离。例如this和his的最小编辑距离为1。


由于字符替换可以分解为插入和删除两步,所以又有一些人将最小编辑距离定义为将一个字符串s变为另一个字符串t所需要的最小代价。插入、删除、替换的代价分别是1、1、2。字符替换操作的时候,如果字符从c1和字符c2相同,则将c1替换为c2的代价为0,否则为2。本文给出的最小编辑距离以代价来计算。



二、算法原理


懒得画电脑图,以手工图扫描文件来代替,将就着看吧。



三、环境


Win7中文旗舰版64位 + Python 3.64 64位 + MinGW GCC4.5.2



四、C代码


#include <stdio.h>

#include <string.h>


#define M 100

#define N 100

#define CHAR_LEN_MAX 5

#define INS_COST 1

#define DEL_COST 1

#define SUB_COST 2


char ss[M][CHAR_LEN_MAX], tt[N][CHAR_LEN_MAX];


int getWordsFromSentence(char sen[], char chars[][CHAR_LEN_MAX])

{

int count = 0;

char *p = sen;

char *q = chars[count];

q[0] = '\0';

while (*p)

{

if (*p>0)

{

q[0] = *p;

q[1] = '\0';

}

else

{

q[0] = *p;

q[1] = *(p+1);

q[2] = '\0';

p++;

}

if (*p)

p++;

q = chars[++count];

q[0] = '\0';

}

return count;

}



int main()

{

/* 定义变量 */

int d[N+1][M+1];

char s[M], t[N];

int i, j;

int x, y, z, min;

int m = M+1, n = N + 1;


/* 输入源字符串和目标字符串并求它们的长度 */

do

{

if (m>M || m<1)

{

printf("请输入源字符串(非空字符串,长度不能超过%d个字节,一个汉字算两个字节):", M);

gets(s);

m = strlen(s);

}

if (n>N || n<1)

{

printf("请输入目标字符串(非空字符串,长度不能超过%d个字节,一个汉字算两个字节):", N);

gets(t);

n = strlen(t);

}

}

while (m>M || n>N || m<1 || n<1);



/* 将源字符串和目标字符串分解成一个个的字符,存入相应的二维字符数组 */

m = getWordsFromSentence(s, ss);

n = getWordsFromSentence(t, tt);

printf("\ns:");

for (i=0; i<m; i++)

printf("%s  ", ss[i]);

printf("\nt:");

for (i=0; i<n; i++)

printf("%s  ", tt[i]);

/* 最小距离矩阵赋初值 */

d[0][0] = 0;

for (i=1; i<=m; i++)

d[0][i] = d[0][i-1] + DEL_COST;

for (i=1; i<=n; i++)

d[i][0] = d[i-1][0] + INS_COST;


/* 计算最小距离矩阵的其它元素值 */

for (i=1; i<=n; i++)

{

for (j=1; j<=m; j++)

{

x = d[i-1][j] + INS_COST;

if (strcmp(tt[i-1],ss[j-1])==0)

y = d[i-1][j-1];

else

y = d[i-1][j-1] + SUB_COST;

z = d[i][j-1] + DEL_COST;

min = (x<y)?x:y;

min = (min<z)?min:z;

d[i][j] = min;

}

}


printf("\n\n最小编辑距离矩阵\n");

for (j=m; j>=0; j--)

{

for (i=0; i<=n; i++)

printf("%5d", d[i][j]);

printf("\n");

}


printf("\n\n源串:%s\n目标串:%s\n最小编辑距离:%d\n", s, t, d[n][m]);


return 0;

}



五、Python代码




六、比较


C代码只给出了最小编辑距离的一种非递归实现,Python代码给出了递归和非递归两种实现方法。经过对同一个字符串对("intention"和"execution")求最小编辑距离200次发现:

递归法用时:270.928724 秒

非递归法用时:0.015600 秒

可以看出,递归算法的速速远远比不上非递归算法。



七、结论


虽然递归算法在理解算法方面有优势,但是在运行速度方面实在是不敢恭维,因此,对于一些具体应用,如果能用非递归算法实现就不要用递归算法来实现。


文章转载自语和言,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论