经典题,《编程之美》里有,但是书上那个程序好像有问题,也不太让人清晰明朗
问题:找出字符串的编辑距离,即把一个字符串s1最少经过多少步操作变成编程字符串s2,操作有三种,添加一个字符,删除一个字符,修改一个字符。
例如 将kitten一字转成sitting:
-
sitten (k→s)
-
sittin (e→i)
-
sitting (→g)
俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。
如果有两个字符串A和B,如果它们的第一个字符是相同的,只要计算A[2,…,lenA]和B[2,…,lenB]的距离。如果它们的第一个字符是不相同的,那么可以进行如下的操作。
1. 删除A的第一个字符,然后计算A[2,…,lenA]和B[1,…,lenB]的距离;
2. 删除B的第一个字符,然后计算A[1,…,lenA]和B[2,…,lenB]的距离;
3. 修改A的第一个字符为B的第一个字符,然后计算A[2,…,lenA]和B[2,…,lenB]的距离;
4. 修改B的第一个字符为A的第一个字符,然后计算A[2,…,lenA]和B[2,…,lenB]的距离;
5. 增加A的第一个字符到B第一个字符之前,然后计算A[2,…,lenA]和B[1,…,lenB]的距离;
6. 增加B的第一个字符到A第一个字符之前,然后计算A[1,…,lenA]和B[2,…,lenB]的距离。
从上面的分析可以看出,如果A和B的第一个字符不相同,那么可以不管之后会变成什么样,就可以把上面的6个操作合并成下面3个。
1. 一步操作之后,计算A[2,…,lenA]和B[1,…,lenB]的距离;
2. 一步操作之后,计算A[1,…,lenA]和B[2,…,lenB]的距离;
3. 一步操作之后,计算A[2,…,lenA]和B[2,…,lenB]的距离。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MIN(x,y) ((x)<(y)?(x):(y))
static int distance(char * str1,char * str2)
{
if(strlen(str1) == 0 || strlen(str2) == 0)
{
return abs(strlen(str1) - strlen(str2));
}
if(str1[0] == str2[0])
{
return distance(str1 +1,str2 + 1);
}
int t1,t2,t3;
t1 = distance(str1,str2 + 1);
t2 = distance(str1 + 1,str2);
t3 = distance(str1 + 1, str2 + 1);
return MIN(MIN(t1,t2),t3) + 1;
}
int main()
{
char * s1 = "kitten";
char * s2 = "sitting";
printf("distance = %d\n",distance(s1,s2));
}
参考:https://blog.csdn.net/u012067392/article/details/73135724