描述 | |
---|---|
知识点 | 字符串 |
运行时间限制 | 10M |
内存限制 | 128 |
输入 | 输入两个字符串 |
输出 | 得到计算结果 |
样例输入 | abcdefg abcdef |
样例输出 | 1 |
这个题目和计算两个字符串的相似度是一样的。点击打开链接
很经典的可使用动态规划方法解决的题目,和计算两字符串的最长公共子序列相似。
设Ai为字符串A(a1a2a3 … am)的前i个字符(即为a1,a2,a3 … ai)
设Bj为字符串B(b1b2b3 … bn)的前j个字符(即为b1,b2,b3 … bj)
设 L(i,j)为使两个字符串和Ai和Bj相等的最小操作次数。
当ai==bj时 显然 L(i,j) = L(i-1,j-1)
当ai!=bj时
若将它们修改为相等,则对两个字符串至少还要操作L(i-1,j-1)次
若删除ai或在bj后添加ai,则对两个字符串至少还要操作L(i-1,j)次
若删除bj或在ai后添加bj,则对两个字符串至少还要操作L(i,j-1)次
此时L(i,j) = min( L(i-1,j-1), L(i-1,j), L(i,j-1) ) + 1
显然,L(i,0)=i,L(0,j)=j, 再利用上述的递推公式,可以直接计算出L(i,j)值。
#include<iostream>
#include<string>
using namespace std;
int caldistance(string ,string);
int min_value(int ,int,int);
int main()
{
string s1,s2;
cin>>s1>>s2;
cout<<caldistance(s1,s2);
//system("pause");
return 0;
}
int caldistance(string s1,string s2)
{
int len1=s1.size()+1;
int len2=s2.size()+1;
int ** cnt=new int*[len1];
for(int i=0;i<len1;i++)
cnt[i]=new int[len2];
for(int i=0;i<len1;i++)
cnt[i][0]=i;
for(int j=0;j<len2;j++)
cnt[0][j]=j;
for(int i=1;i<len1;i++)
for(int j=1;j<len2;j++)
if(s1[i-1]==s2[j-1])
cnt[i][j]=cnt[i-1][j-1];
else
{
cnt[i][j]=min_value(cnt[i-1][j-1],cnt[i-1][j],cnt[i][j-1])+1;
}
int ret=cnt[len1-1][len2-1];
for(int i=0;i<len1;i++)
delete [] cnt[i];
delete [] cnt;
return ret;
}
int min_value(int a,int b,int c)
{
int min;
if(a<b)
min=a;
else
min=b;
if(min>c)
min=c;
return min;
}