文字列の類似性アルゴリズム(編集距離)

1.コンセプト

  二つの文字列間の編集距離は、他の所望に編集操作の最小数で変換を指します。(3)文字を削除し、(2)文字を挿入し、(1)別の文字に1つの文字を置き換えますと、編集操作を許可します。

  相互の「編集距離+1」に等しい類似性、。

2.分析

  [0 ... n]を持つ文字列、B [0 ... M]。

  (1)場合には[I] = bの[J]、編集操作は、この時点で説明する必要はありません。編集距離ホルダー、すなわちF(I、J)= F(I-1、J-1)

  (2)3つの編集操作がある場合は、[I]!= B [j]のとき。

  前記インサートとのみに影響添字IまたはJを削除します。「G」場合は、以下の図のように、現在(T1、T2)と一致するように、インデックスのみのT1を変更、削除。

  前記交換作業、添字2は影響を与えることになります。「G」は「M」に置き換えた場合、時電流(T1、T2)と一致するには、以下の図のような、次の時刻(T1 + 1、T 2 + 1)で実行される必要があります。

  これは、次の漸化式と推定することができます。

  

3.再帰を使用してコードを解きます

#include<stdio.h>
#include<string.h>
char *a="abcgh";
char *b="aecdgh";
int min(int t1,int t2,int t3)   ///求三个数的最小值
{
    int min;
    min=t1<t2?t1:t2;
    min=min<t3?min:t3;
    return min;
}
int calculate(int i,int enda,int j,int endb)
{
    int t1,t2,t3;
    if(i>enda)  ///i指示超过a[]的范围时
    {
        if(j>endb)
            return 0;
        else
            return endb-j+1;
    }
    if(j>endb)  ///j指示超过b[]的范围时
    {
        if(i>enda)
            return 0;
        else
            return enda-i+1;
    }
    if(*(a+i) == *(b+j))    ///如果两个相等,则直接求下一个位置
        return calculate(i+1,enda,j+1,endb);
    else
    {
        t1=calculate(i+1,enda,j,endb);  ///删除a[i]或在b中插入a[i]
        t2=calculate(i,enda,j+1,endb);  ///删除b[j]或在a中插入b[j]
        t3=calculate(i+1,enda,j+1,endb);    ///替换
        return 1+min(t1,t2,t3);
    }
}
int main()
{
    int dis=calculate(0,strlen(a)-1,0,strlen(b)-1);
    printf("dis=%d",dis);
    return 1;
}

4.動的プログラミングを使用してコードを解きます

#include<stdio.h>
#include<string.h>
#define MAX 1000
int dp[MAX][MAX];   ///dp[i][j]表示当前a[0..i-1]与b[0..j-1]的编辑距离
char *a="agbgd";
char *b="ggd";

int min(int t1,int t2,int t3)   ///求三个数的最小值
{
    int min;
    min=t1<t2?t1:t2;
    min=min<t3?min:t3;
    return min;
}

int main()
{
    int i,j;
    int lena=strlen(a),lenb=strlen(b);
    memset(dp,0,sizeof(dp));
    for(i=0;i<=lena;i++)   ///a作为行,当b为空串时
        dp[0][i]=i;
    for(i=0;i<=lenb;i++)   ///b作为列,当a为空串时
        dp[i][0]=i;

    for(i=1;i<=lena;i++)
    {
        for(j=1;j<=lenb;j++)
        {
            if(*(a+i)==*(b+j))  ///相等时
                dp[i][j]=dp[i-1][j-1];
            else
                dp[i][j]=1+min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]); ///不相等时,取三种可能操作的最小数值+1
        }
    }
    printf("编辑距离为:dis=%d\n",dp[lena][lenb]);
    return ;
}

おすすめ

転載: www.cnblogs.com/myblog1993/p/11485714.html