您的位置:首页 > 其它

字符串编辑距离问题

2018-03-07 17:01 225 查看

一、问题

给定一个源串S和目标串T,能够对源串进行如下操作:
1)在任意位置上插入一个字符
2)替换任意字符
3)删除任意字符
写一个程序,实现返回最小操作次数,使得对源串S进行上述这些操作后等于目标串T
【例如】
将kitten一字转成sitting:
step1: sitten (k→s)
step2:sittin (e→i)
step3:sitting (→g)

二、分析

        假定我们现在正在求解dist(str1+char1, str2+char2),也就是把"str1+char1"转变成"str2+char2"。在这个转变过称中,我们要分情况讨论:
1、str1可以直接转变成str2。这时我们只要把char1转成char2就可以了(如果char1 != char2)。
2、str1+char1可以直接转变成str2。这时我们处理的方式是插入char2。
3、str1可以直接转成str2+char2。这时的情况是我们需要删除char1。
综合上面三种情况,dist(str1+char1, str2+char2)应该是三者的最小值。

三、解析

首先定义这样一个函数——dist(i, j),它表示第一个字符串的长度为i的子串到第二个字符串的长度为j的子串的编辑距离。
显然可以有如下动态规划公式
    1)if i == 0 且 j == 0,dist(i, j) = 0
    2)if i == 0 且 j > 0,dist(i, j) = j
    3)if i > 0  且 j == 0,dist(i, j) = i
    4)if i ≥ 1  且 j ≥ 1 ,dist(i, j) == min{ dist(i-1, j) + 1, dist(i, j-1) + 1, dist(i-1, j-1) + f(i, j) },当第一个字符串的第i个字符不等于第二个字符串的第j个字符时,f(i, j) = 1;否则,f(i, j) = 0。以上描述参考自文章:http://www.cnblogs.com/jiabei521/p/3353390.html 

四、代码实现

/*****************************
Author:tmw
Date:2018-3-7
******************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**
SourceStr:为源串
TargetStr:为目标串

根据题目的意思是比着目标串对源串进行更改
**/

int min( int a, int b )
{
return a<b?a:b;
}

int min_distance_of_string(char* SourceStr, char* TargetStr)
{
int SourLen = strlen(SourceStr);
int TarLen = strlen(TargetStr);
char dis[SourLen][TarLen];
int i,j;

/**构建字符串编辑距离解的二维数组**/

//初始化当源串或者目标串为空的时候,所耗费的编辑距离--即动态规划公式中的第1)~3)
printf("sourcelen = %d\n",SourLen);
printf("targetlen = %d\n",TarLen);
dis[0][0] = 0;
for( i=1; i<=SourLen; i++ )
dis[i][0] = i;
for( j=1; j<=TarLen; j++ )
dis[0][j] = j;

for( i=1; i<=SourLen; i++ )
{
for( j=1; j<=TarLen; j++ )
{
//字符串中的下标是从0开始的,因此这里减一
if( SourceStr[i-1] == TargetStr[j-1] )
dis[i][j] = dis[i-1][j-1];
else
dis[i][j] = 1 + min(dis[i-1][j],dis[i][j-1]);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐