1. 程式人生 > 其它 >演算法第三章上機實驗報告

演算法第三章上機實驗報告

1 題目分析

1.1 問題描述

7-4 編輯距離問題 (25 分)

設A和B是2個字串。要用最少的字元操作將字串A轉換為字串B。這裡所說的字元操作包括 (1)刪除一個字元; (2)插入一個字元; (3)將一個字元改為另一個字元。 將字串A變換為字串B所用的最少字元運算元稱為字串A到 B的編輯距離,記為d(A,B)。 對於給定的字串A和字串B,計算其編輯距離 d(A,B)。

輸入格式:
第一行是字串A,檔案的第二行是字串B。

提示:字串長度不超過2000個字元。

輸出格式:
輸出編輯距離d(A,B)

輸入樣例:
在這裡給出一組輸入。例如:
fxpimu xwrs
結尾無空行

輸出樣例:
在這裡給出相應的輸出。例如:
5

1.2 演算法描述

首先的想法是,從兩個字串的首位置開始比較。
(1)如果兩個字串的首位置字母相同,那麼遞迴比較剩下的字串
(2)如果兩個字串的首位置字母不相同,那麼對首字母進行刪除、插入、或者替換操作,再遞迴處理後面的部分。
這樣的話會有大量重複計算,不如直接用動態規劃,開一個新的陣列記錄子問題的最優解,一步步找到答案。

用op[2010][2010]來儲存結果,op[i][j]表示a的子串(下標從0到i)轉化為b的子串(下標從0到j)需要的操作次數,最後輸出的答案就是op[lena][lenb]

1.3 問題求解:

1.1.1 根據最優子結構性質,列出遞迴方程式

op[i][0](i從0到lena)初始化為i,op[0][j](j從0到lenb)初始化為j。(因為當i或j行為0時,要想將a子串轉化為b子串,只能全部增加或者全部刪除)

初始化完畢之後:
(1)如果兩個字串的首位置字母相同,op[i][j]=op[i-1][j-1](不用進行額外操作,操作次數就是上一個子串的操作次數)
(2)如果兩個字串的首位置字母不相同:
刪除:刪除a子串的末尾,意味著op[i][j]=1+op[i-1][j]
插入:在a子串的末尾插入,意味著op[i][j]=1+op[i][j-1]
將一個字元改為另一個字元:意味著op[i][j]=1+op[i-1][j-1]
然後要找出這三種方案中的最小值,所以遞迴式如下:

1.1.2 給出填表法中表的維度、填表範圍和填表順序

標的維度:二維
填表範圍:i從1到 lena(a字串的長度),j從1到 lenb(b字串的長度)
填表順序:從左到右,從上到下填表。(因為填一個格子的時候要保證他的上面,左邊,對角線的都填了)

1.1.3 分析該演算法的時間和空間複雜度

時間複雜度:O(mn)(雙重迴圈)
空間複雜度:O(mn)(額外開了個二維陣列)

1.3 心得體會(對本次實踐收穫及疑惑進行總結)

這道題一開始是不會的,想了很久都沒想出來,後面上網看了別人解析。
我自己沒想到的部分就是,當兩個字母不等的時候,進行了三個操作之後可以先刪除再+1,就是分為三種情況遞迴,然後選擇運算元最小的那個。

2.你對動態規劃演算法的理解和體會

首先,動態規劃應該依賴於兩個最重要的性質:最優子結構和重疊子問題。

判斷一道題是否能用動態規劃,首先判斷它是否有最優子結構,就是說,他最終的問題的答案,是不是由一個個小問題的最優解逐步構造出的。然後要看是不是由重疊的子問題,這時候就需要用到一個備忘錄記錄之前已經計算過的資料,避免重複計算,保證了每個子問題只解一次。

其次,通過這段時間對動態規劃的學習,我明白了動態規劃演算法最重要的就是填表和寫遞迴式。要明確填表用何種方式填,填這個空的時候我需要旁邊哪幾個空的答案。遞迴式則需要我們根據題目建立遞迴關係,有了遞迴關係就可以愉快地寫程式碼了!