【動態規劃】字串最小編輯距離Java實現
問題:給定一個源串和目標串,能夠對源串進行如下操作:
在給定位置上插入一個字元
替換任意字元
刪除任意字元
要求寫一個程式,返回最少的運算元,使得對源串進行這些操作後等於目標串。源串和目標串的長度都小於2000。
關於編輯距離
編輯距離(Edit Distance),又稱Levenshtein距離,是指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數。許可的編輯操作包括將一個字元替換成另一個字元,插入一個字元,刪除一個字元。
例如:字串abc和字串adbe之間的最小編輯距離是2 因為adbe刪除b然後將e替換為c經過這兩部
a[m]表示第一個字串,m表示該字串字元的下標為0~m
b[n]表示第二個字串,n表示該字串字元的下標為0~n
d[i][j]表示子串a[i]和子串a[j]的最小編輯距離
那麼邊界條件:
d[i][0]=i, 0=<i<=m
d[0][j]=j, 0=<j<=n
狀態轉移方程:d[i][j]=min{d[i-1][j]+1,d[i][j-1]+1,d[i-1][j-1]+lastCharCommon}
lastCharCommon=1,如果a[i-1]等於b[j-1]
lastCharCommon=0,如果a[i-1]不等於b[j-1]
下邊給出java實現:
class StringEditDistance{ /*輸入兩個字串,返回這兩個字串的編輯距離*/ public static int getDistance(String strA, String strB){ int distance=-1; /*輸入引數合法性檢查*/ if(null==strA||null==strB||strA.isEmpty()||strB.isEmpty()){ return distance; } /*兩個字串相等,編輯距離為0*/ if (strA.equals(strB)) { return 0; } System.out.println("第一個字串:"+strA); System.out.println("第二個字串:"+strB); int lengthA=strA.length(); int lengthB=strB.length(); int length=Math.max(lengthA,lengthB); /*申請一個二維陣列,儲存轉移矩陣*/ int array[][]=new int[length+1][length+1]; /*邊界條件初始化*/ for(int i=0;i<=length;i++){ array[i][0]=i; } /*邊界條件初始化*/ for(int j=0;j<=length;j++){ array[0][j]=j; } /*狀態轉移方程*/ for(int i=1;i<=lengthA;i++){ for(int j=1;j<=lengthB;j++){ array[i][j]=min(array[i-1][j]+1, array[i][j-1]+1, array[i-1][j-1]+(strA.charAt(i-1)==strB.charAt(j-1)?0:1)); } } /*列印轉移表格*/ System.out.println("狀態轉移表格:"); for(int i=0;i<=lengthA;i++){ for(int j=0;j<=lengthB;j++){ System.out.print( array[i][j]+" "); } System.out.println(); } return array[lengthA][lengthB]; } /*取三個數中的最小值*/ public static int min(int a,int b, int c){ return Math.min(Math.min(a,b),c); } }
測試用例:
String a=null; String b="abd"; System.out.println("case 1:編輯距離為:"+StringEditDistance.getDistance(a,b)); System.out.println(); a="Program"; b="P-r-o-g-r-a-m"; System.out.println("case 2:編輯距離為"+StringEditDistance.getDistance(a,b)); System.out.println(); a="2333"; b="6666666"; System.out.println("case 3:編輯距離為"+StringEditDistance.getDistance(a,b)); System.out.println(); a="adbe"; b="abc"; System.out.println("case 4:編輯距離為"+StringEditDistance.getDistance(a,b)); System.out.println(); a="hehe"; b="hehe"; System.out.println("case 5:編輯距離為"+StringEditDistance.getDistance(a,b)); System.out.println();
執行結果:
第一個字串:Program
第二個字串:P-r-o-g-r-a-m
狀態轉移表格:
0 1 2 3 4 5 6 7 8 9 10 11 12 13
1 0 1 2 3 4 5 6 7 8 9 10 11 12
2 1 1 1 2 3 4 5 6 7 8 9 10 11
3 2 2 2 2 2 3 4 5 6 7 8 9 10
4 3 3 3 3 3 3 3 4 5 6 7 8 9
5 4 4 3 4 4 4 4 4 4 5 6 7 8
6 5 5 4 4 5 5 5 5 5 5 5 6 7
7 6 6 5 5 5 6 6 6 6 6 6 6 6
case 2:編輯距離為6
第一個字串:2333
第二個字串:6666666
狀態轉移表格:
0 1 2 3 4 5 6 7
1 1 2 3 4 5 6 7
2 2 2 3 4 5 6 7
3 3 3 3 4 5 6 7
4 4 4 4 4 5 6 7
case 3:編輯距離為7
第一個字串:adbe
第二個字串:abc
狀態轉移表格:
0 1 2 3
1 0 1 2
2 1 1 2
3 2 1 2
4 3 2 2
case 4:編輯距離為2
case 5:編輯距離為0
相關文章
- 動態規劃-編輯距離動態規劃
- Leetcode 編輯距離(動態規劃)LeetCode動態規劃
- 怎樣衡量兩個字串的相似度(編輯距離動態規劃求解)字串動態規劃
- 演算法——動態規劃演算法求解字串的編輯距離演算法動態規劃字串
- 演算法:編輯距離問題(動態規劃,詳細解答)演算法動態規劃
- 計算字串編輯距離字串
- 最長公共子序列與最小編輯距離-你有更快的演算法麼?演算法
- PHP使用動態規劃實現最優紅包組合PHP動態規劃
- 詳解動態規劃最長公共子序列--JavaScript實現動態規劃JavaScript
- Hetao P2071 打字遊戲 題解 [ 綠 ] [ 最小生成樹 ] [ 動態規劃 ] [ 編輯距離 ]遊戲動態規劃
- 字串編輯距離問題詳解字串
- Levenshtein:計算字串的編輯距離字串
- 最長公共子序列&迴文字串 nyoj動態規劃字串動態規劃
- 動態規劃——字串分割(Word Break)動態規劃字串
- 動態規劃8:最優編輯str1-->str2動態規劃
- 編輯距離及編輯距離演算法演算法
- 動態規劃:最長上升子序列動態規劃
- 最長上升子序列動態規劃動態規劃
- 動態規劃求最長降序序列動態規劃
- 動態規劃-最長公共子序列動態規劃
- 動態規劃——最長公共子序列動態規劃
- 834. 樹中距離之和-困難-樹、圖、動態規劃、深度優先搜尋動態規劃
- 【DP專輯】ACM動態規劃總結ACM動態規劃
- “最長公共字串子序列”問題的動態規劃法演算法字串動態規劃演算法
- 【動態規劃(一)】動態規劃基礎動態規劃
- 【演算法資料結構Java實現】Java實現動態規劃(揹包問題)演算法資料結構Java動態規劃
- 動態規劃-最長上升子序列模型動態規劃模型
- 動態規劃(最長公共子序列LCS)動態規劃
- 動態規劃---求硬幣最優解動態規劃
- 使用動態規劃 實現字元級Diff & Patch動態規劃字元
- 動態規劃實現O(n)爆破任意加密動態規劃加密
- 【DP】編輯距離
- Java LeetCode 72. 編輯距離JavaLeetCode
- 動態規劃動態規劃
- RQNOJ 514 字串距離:dp & 字串字串
- [動態規劃] 六、最長迴文子串動態規劃
- 動態規劃7:最長上升子序列LIS動態規劃
- 醜數問題——動態規劃、Java動態規劃Java