- 我们把字符串的相似度定义:将一个字符串转化为另一个字符串的时需要付出的代价。可以采用插入、删除、替换、三种方式编辑,代价就是编辑的次数。以SNOWY转化为SUNNY为例。
- 转换1:S-NOWY
- SUNN-Y转换的代价为3;(插入U,替换O,删除W);
- 转换2:-SNOW-Y
- SUN--NY 代价为5(插入S,替换S,删除O,删除W,插入N)
假设我将问题定义求解source的[1~n]个字符转换target[1~m]个字符的最少的编辑次数,本问题的最优子结构求解source的[1~i]个字符转换target[1~j]个字符的最少的编辑次数,将状态的d[i,j]定义为从source的[1~i]个字符转换target[1~j]个字符的最少的编辑距离。
d[i,j]递推关系分为两种情况:
- d[i,j]=d[i-1,dj-1]+0;source[i]==target[j];
- d[i,j]=min(d[i-1,j]+1 ,d[i,j-1]+1; d[i-1,j-1]+1)source[i]!=target[j];
- traget字符串为空时编辑距离相当source字符串删除的次数,确定的边界条件d[i,0]=source的字符串的长度;
- source字符串为空时编辑距离相当与插入target字符的次数,边界条件为d[0,j]=target字符串的长度;
代码如下:
#include <iostream>
#include<string.h>
using namespace std;
int EditDistance(char *src,char *dest)
{
int i,j;
int d[31][31]={0xFFFF} ;
for(i=0;i<=strlen(src);i++)//不同字符串的边界条件
d[i][0]=i;
for(j=0;j<=strlen(dest);j++)//不同字符串的边界条件
d[0][j]=j;
for(i=1;i<=strlen(src);i++)
{
for(j=1;j<=strlen(dest);j++)
{
if(src[i]==dest[j])//当字符相同时,编辑距离
{
d[i][j]=d[i-1][j-1];
}
else//不同时的编辑距离
{
int edIns=d[i][j-1]+1;//对字符进行插入操作
int edDel=d[i-1][j]+1;//对字符串进行删除操作
int edRep=d[i-1][j-1]+1;//对字符串进行替换操作
d[i][j]=min(min(edIns,edDel),edRep);
}
}
}
return d[strlen(src)][strlen(dest)];
}
int main()
{
//char a[30],b[30];
char a[30];
char b[30];
strcpy(a,"SNOWY");//传递字符数组
strcpy(b,"SUNNY");
//count<<a;
int num=EditDistance(a,b);
cout<<num<<endl;
return 0;
}
//这个问题的核心是将一个复杂的问题变小化,例如可以使用从一个字符编到两个字符来推理
#include<string.h>
using namespace std;
int EditDistance(char *src,char *dest)
{
int i,j;
int d[31][31]={0xFFFF} ;
for(i=0;i<=strlen(src);i++)//不同字符串的边界条件
d[i][0]=i;
for(j=0;j<=strlen(dest);j++)//不同字符串的边界条件
d[0][j]=j;
for(i=1;i<=strlen(src);i++)
{
for(j=1;j<=strlen(dest);j++)
{
if(src[i]==dest[j])//当字符相同时,编辑距离
{
d[i][j]=d[i-1][j-1];
}
else//不同时的编辑距离
{
int edIns=d[i][j-1]+1;//对字符进行插入操作
int edDel=d[i-1][j]+1;//对字符串进行删除操作
int edRep=d[i-1][j-1]+1;//对字符串进行替换操作
d[i][j]=min(min(edIns,edDel),edRep);
}
}
}
return d[strlen(src)][strlen(dest)];
}
int main()
{
//char a[30],b[30];
char a[30];
char b[30];
strcpy(a,"SNOWY");//传递字符数组
strcpy(b,"SUNNY");
//count<<a;
int num=EditDistance(a,b);
cout<<num<<endl;
return 0;
}
//这个问题的核心是将一个复杂的问题变小化,例如可以使用从一个字符编到两个字符来推理