计算字符串的相似度

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

  1. 修改一个字符(“a”——>“b”)
  2. 增加一个字符(“abdd”——>“aebdd”)
  3. 删除一个字符(“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();

    }

你可能感兴趣的:(字符串)