編輯距離

給定兩個字符串S和T,對於T我們允許三種操作:
(1) 在任意位置添加任意字符 (2) 刪除存在的任意字符 (3) 修改任意字符 
問最少操作多少次可以把字符串T變成S? 
例如: S=  “ABCF”   T = “DBFG”
那麼我們可以
(1) 把D改爲A (2) 刪掉G (3) 加入C
所以答案是3。
分析: 這個最少的操作次數,通常被稱之爲編輯距離。“編輯距離”一次本身具有最短的意思在裏面。因爲題目有“最短”這樣的關鍵詞,首先我們想到的是BFS。是的,當S的距離爲m, T的距離爲n的時候,我們可以找到這樣的操作次數的界限:
(1) 把T中字符全刪了,再添加S的全部字符,操作次數m + n。 (2) 把T中字符刪或加成m個,再修改 操作次數最多 |n – m| + m。 雖然,我們找到了這樣的上界,BFS從實際角度並不可行,因爲搜索空間是指數的,這取決於S中的字符種類——具體的數量級不好估計。
最後,我們來提供輸入輸出數據,由你來寫一段程序,實現這個算法,只有寫出了正確的程序,才能繼續後面的課程。
輸入
第1行:字符串a(a的長度 <= 1000)。
第2行:字符串b(b的長度 <= 1000)。

輸出

輸出a和b的編輯距離

輸入示例

kitten
sitting

輸出示例

3

請選取你熟悉的語言,並在下面的代碼框中完成你的程序,注意數據範圍,最終結果會造成Int32溢出,這樣會輸出錯誤的答案。
不同語言如何處理輸入輸出,請查看下面的語言說明。
題解:dp[i][j]表示S前i個和T前j個要扣的最少分。
1:當S[i]和T[j]相同時,那麼這種情況下最少要扣的分數是dp[i-1][j-1];
2:當S[i]和T[j]不同時,那麼這種情況下最少要扣的分數是 dp[i-1][j-1]+1和(S的前i個和T的前j-1個已經對齊)dp[i][j-1]+1和
(S的前i-1個和T的前j個已經對齊)dp[i-1][j]+1的最小值;
此時得出狀態轉移方程,實現代碼對你來說肯定輕而易舉啦。(此種方法複雜度O(n^2))
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[1010][1010];
int main()
{
    char a[1010];
    char b[1010];
    scanf("%s %s",a+1,b+1);
    a[0]=b[0]='0';
    int l1=strlen(a)-1;
    int l2=strlen(b)-1;
    for(int i=0;i<=l1;i++){
        dp[i][0]=i;
    }
    for(int i=0;i<=l2;i++)
    dp[0][i]=i;
    for(int i=1;i<=l1;i++){
        for(int j=1;j<=l2;j++){
            if(a[i]!=b[j]){
                dp[i][j]=min(dp[i-1][j]+1,min(dp[i-1][j-1]+1,dp[i][j-1]+1));
            }else{
                dp[i][j]=dp[i-1][j-1];
            }
        }
    }
    printf("%d",dp[l1][l2]);
    return 0;
}





發佈了36 篇原創文章 · 獲贊 6 · 訪問量 9763
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章