计算字符串的相似度

题目:定义一套操作方法将两个不相同的字符串变得相同,具体操作如下:

修改一个字符(“a”——>“b”) 增加一个字符(“abdd”——>“aebdd”) 删除一个字符(“travelling”——>“traveling”)

字符串的距离s:使两个字符串相等的操作

相似度:1/(s+1)。

思路:

字符串a:长度m

字符串b:长度n

计算使得a[1..m]和b[1..n]相同需要变换的次数:

当a[1] == b[1]:计算a[2..m]和b[2..n]

当a[1] != b[1]

1.删除a中第一个字符:计算a[2..m]和b[1..n]

2.删除b中第一个字符:计算a[1..m]和b[2..n]

3.修改a中第一个字符:计算a[2..m]和b[2..n]

4.修改b中第一个字符:计算a[2..m]和b[2..n]

5.增加a串中的第一个字符到b串前:计算a[2..m]和b[1..n]

6.增加b串中的第一个字符到a串前:计算a[1..m]和b[2..n]

一次操作后,计算:

a[2..m]和b[1..n]

a[1..m]和b[2..n]

a[2..m]和b[2..n]

使用递归可以容易解答:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

int min(int x, int y){

if(x > y){

return y;

}else{

return x;

}

}

int caculate(char a[], int startA, int endA, char b[], int startB, int endB){

int t1=0, t2=0, t3=0, tmp=0;

//注意出口条件

if(startA > endA){

if(startB > endB){

return 0;

}else{

return endB - startB + 1;

}

}

if(startB > endB){

if(startA > endA){

return 0;

}else{

return endA - startA + 1;

}

}

if(a[startA] == b[startB]){

return caculate(a,startA+1,endA,b,startB+1,endB);

}else{

t3 = caculate(a,startA,endA,b,startB+1,endB);

t1 = caculate(a,startA+1,endA,b,startB,endB);

t2 = caculate(a,startA+1,endA,b,startB+1,endB);

tmp = min(t1,t2);

return min(tmp,t3) + 1;

}

}

int main(){

char a[100],b[100];

int lenA, lenB ,ret;

scanf("%s%s",a,b);

lenA = strlen(a);

lenB = strlen(b);

ret = caculate(a,0,lenA-1,b,0,lenB-1);

printf("%d",ret);

system("pause");

return main();

}

使用备忘录对上述递归进行改进:

flag[i][j]表示a[i][lenA-1]和b[j][lenB-1]的变换次数:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

int flag[100][100];

int min(int x, int y){

if(x > y){

return y;

}else{

return x;

}

}

int caculate(char a[], int startA, int endA, char b[], int startB, int endB){

int t1=0, t2=0, t3=0, tmp=0;

//出口条件

if(startA > endA){

if(startB > endB){

return 0;

}else{

flag[startA][startB] = endB - startB + 1;

return endB - startB + 1;

}

}

if(startB > endB){

if(startA > endA){

return 0;

}else{

flag[startA][startB] = endA - startA + 1;

return endA - startA + 1;

}

}

if(a[startA] == b[startB]){

if(flag[startA+1][startB+1] > 0){

return flag[startA+1][startB+1];

}else{

flag[startA][startB] = caculate(a,startA+1,endA,b,startB+1,endB);

return flag[startA][startB];

}

}else{

if(flag[startA][startB+1] > 0){

t1 = flag[startA][startB+1];

}else{

t1 = caculate(a,startA,endA,b,startB+1,endB);

}

if(flag[startA+1][startB] > 0){

t2 = flag[startA+1][startB];

}else{

t2 = caculate(a,startA+1,endA,b,startB,endB);

}

if(flag[startA+1][startB+1] > 0){

t3 = flag[startA+1][startB+1];

}else{

t3 = caculate(a,startA+1,endA,b,startB+1,endB);

}

tmp = min(t1,t2);

flag[startA][startB] = min(tmp,t3) + 1;

return flag[startA][startB];

}

}

int main(){

char a[100],b[100];

int lenA, lenB ,ret,i,j;

scanf("%s%s",a,b);

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

for(j=0; j<100; j++)

flag[i][j] = 0;

lenA = strlen(a);

lenB = strlen(b);

ret = caculate(a,0,lenA-1,b,0,lenB-1);

printf("%d",ret);

system("pause");

return main();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值