編輯距離問題

2021-08-18 16:49:43 字數 2580 閱讀 2057

給定兩個字串s和t,對於t我們允許三種操作:

(1) 在任意位置新增任意字元

(2) 刪除存在的任意字元

(3) 修改任意字元 

問最少操作多少次可以把字串t變成s? 

例如: s=  「abcf」   t = 「dbfg」

那麼我們可以

(1) 把d改為a

(2) 刪掉g

(3) 加入c

所以答案是3。 輸入

第1行:字串a(a的長度 <= 1000)。

第2行:字串b(b的長度 <= 1000)。

輸出

輸出a和b的編輯距離

輸入示例

kitten

sitting

輸出示例

3

(1) 把t中字元全刪了,再新增s的全部字元,操作次數m + n。

(2) 把t中字元刪或加成m個,再修改 操作次數最多 |n – m| + m。

雖然,我們找到了這樣的上界,bfs從實際角度並不可行,因為搜尋空間是指數的,這取決於s中的字元種類——具體的數量級不好估計。

這個問題之所以難,是難在有「新增」「刪除」這樣的操作,很麻煩。我們試試換個角度理解問題,把它看成字串對齊的問題,事實上從生物資訊學對比基因的角度,我們可以這樣理解問題。

給定字串s和t,我們可以用一種特殊字元促成兩個字串的對齊。我們加的特殊字元是「-」, 我們允許在s和t中任意新增這種特殊字元使得它長度相同,然後讓這兩個串「對齊」,最終兩個串相同位置出現了不同字元,就扣1分,我們要使得這兩個串對齊扣分盡量少。

對於例子 我們實際上採取了這樣的對齊方式:

12345

abcf-

db-fg

注意:如果要對齊,兩個「-」相對是沒有意義的,所以我們要求不出現這種情況。

那麼看一下:

(1) s,t對應位置都是普通字元,相同,則不扣分。 例如位置2,4

(2) s,t對應位置都是普通字元,不同,則扣1分。 例如位置1

(3) s在該位置是特殊字元,t在該位置是普通字元,則扣1分,例如位置5

(4) s在該位置是普通字元,t在該位置是特殊字元,則扣1分,例如位置3

我們來看看扣分專案對應什麼?

(1) 不扣分,直接對應

(2) 對應把t中對應位置的字元修改

(3) 對應在t中刪除該字元

(4) 對應在t中新增該字元

好了,目標明確,感覺像不像 lcs?我們嘗試一下:

設f(i,j)表示s的前i位和t的前j位對齊後的最少扣分。

那我們來看看最後一位,對齊的情況

(1) 必須s[i] == t[j], 這時前i – 1和j – 1位都已經對齊了,這部分肯定要最少扣分。這種情況下最少的扣分是f(i-1,j-1)

(2) 和(1)類似,s[i]≠t[j],這種情況下最少的扣分是f(i -1, j – 1) + 1

(3) s的前i位和t的前(j – 1)位已經對齊了,這部分扣分也要最少。這種情況下最少的扣分是f(i,j-1) + 1

(4) s的前(i-1)位已經和t的前j位對齊了,這部分扣分要最少。這種情況下最少的扣分是f(i,j-1) + 1

具體f(i,j)取什麼值,顯然是要看哪種情況的扣分最少。

為了方便,我們定義函式same(i,j)表示如果s[i] == t[j]則為0,否則為1。

我們來表示一下遞推式:

f(i,j) = min(f(i – 1, j – 1) + same(i,j), f(i – 1,j ) + 1, f(i, j – 1) + 1)

初值是什麼?

f(0, j) = j

f(i, 0) = i

這時因為對於s的前0位,我們只能在之前加入「-」,或者說把t全部刪掉了。類似地,對於t地前0位,我們只能把s的字元都加進來,別無選擇。

注意上述兩個式子的重合點 f(0,0) = 0也符合我們的定義,並不矛盾。

時間複雜度? o(m * n),空間複雜度? o(m * n)。同樣我們發現到f(i,j)只與本行和上一行有關,可以省掉一維的空間複雜度,從而達到o(n)。

優化後的偽**:

for j = 0 to n do

f[j] = j

endfor

for i = 1 to m do

last = f[0]

f[0] = i

for j = 1 to n do

temp = f[i,j]

f[i,j] = min(last + same(i,j), temp + 1, f[j – 1] + 1)

last = temp

endfor

endfor

注意: 我們對於i實際上更新j的順序是由小到達的,所以我們需要儲存「舊的」f[i-1,j – 1]。

我的**

#include #include #include using namespace std;

string a,b,t;

int dp[1020][1020];

int main()

}cout

}

編輯距離問題

問題描述 設a和b是2個字串。要用最少的字元操作將字元a轉化為字元b。字元操作包括 1 刪除乙個人字元。2 插入乙個字元。3 將乙個字元改為另乙個字元。將字串a變換為字串b所用的最少字元運算元稱為字串a到b 的編輯距離,記為d a,b 設計乙個演算法,對給定的任意兩個字串a和b計算出他們的編輯距離d...

編輯距離問題

編輯距離問題 給定兩個字串s和t,對於t我們允許三種操作 1 在任意位置新增任意字元 2 刪除存在的任意字元 3 修改任意字元 問最少操作多少次可以把字串t變成s?例如 s abcf t dbfg 那麼我們可以 1 把d改為a 2 刪掉g 3 加入c 所以答案是3。輸入 第1行 字串a a的長度 1...

編輯距離問題

n題目描述 假設字串的基本操作僅為 刪除乙個字元 插入乙個字元和將乙個字元修改成另乙個字元這三種操作。我們把進行了一次上述三種操作的任意一種操作稱為進行了一步字元基本操作。下面我們定義兩個字串的編輯距離 對於兩個字串a和b,通過上述的基本操作,我們可以把a變成b或b變成a,那麼字串a變成字串b需要的...