動態規劃之編輯距離
1、問題
例如兩個字串 FAMILY 和 FRAME ,有兩種
對齊方式:
1)、
F_A MIL Y
FRAME
2)、
_FAMILY
FRAME
第 2 種對齊需要付出的代價: 5 ,插入 F,將 F 替換為 R ,將 I 替換為 E ,刪除 L 、 Y 。
編輯距離是指將一個字串變換為另一個字串所需要的最小編輯操作。
怎麼找到兩個字串 x [1 ,...,m ] 和 y [1 ,...,n ] 的編輯距離
2、分析
假設已經知道 d [ i ][ j ] 是 X i ={ x 1 ,x 2 ,x 3 ,...,x i } 和 Y j ={ y 1 ,y 2 ,y 3 ,...,y j } 的編輯距離,分3種情況
1)
x1, x2, x3, x4, x(i - 1), x(i)
y1, y2, y3, y4, y(j - 1), _
推出
d [ i ][ j ]= d [ i −1][ j ]+1
2)
x1, x2, x3, x4, x(i - 1), x(i)
y1, y2, y3, y4, y(j - 1), _
推出
d [ i ][ j ]= d [ i ][ j −1]+1
3)
x1, x2, x3, x4, x(i - 1), x(i)
y1, y2, y3, y4, y(j - 1), y(j)
如果x(i) == y(j)推出d [ i ][ j ]= d [ i - 1 ][ j −1] +0,這裡假設diff(i, j) = 0
否則推出d [ i ][ j ]= d [ i - 1 ][ j −1] + 1,這裡假設diff(i, j) = 1
所以
d [ i ][ j ] = min{ d [ i − 1][ j ] + 1, d [ i ][ j − 1] + 1, d [ i − 1][ j − 1] + diff ( i , j )}
然後我們構建一個二維陣列,初始化第一行和第一列按序號增大,為什麼是按照序號增大,比如i=1,j等於1的時候,我們需要操作一步,如果j=2的時候,我們需要操作2步,以此類推,而不是都賦值為0,如下圖
3、程式碼實現
#include <iostream> #include <cstring> using namespace std; #define LEN 1024 char s1[LEN], s2[LEN]; int data[LEN][LEN]; //比較大小的函式 int min(int a, int b) { return a > b ? b : a; } //求最小編輯的函式 int editDistance(char *s1, char *s2, int len1, int len2) { for (int i = 1; i <= len1; ++i) { for (int j = 1; j <= len2; ++j) { int temp = min(data[i][j - 1] + 1, data[i - 1][j] + 1); //這裡不是data[i - 1][j - 1] == data[j][j]; if (s1[i] == s2[j]) { //這裡不是temp = min(temp, data[i - 1][j - 1]); data[i][j] = min(temp, data[i - 1][j - 1]); } else { //這裡不是temp = min(temp, data[i - 1][j - 1] + 1); data[i][j] = min(temp, data[i - 1][j - 1] + 1); } } } return data[len1][len2]; } int main() { std::cout << "請輸入2個字串" << std::endl; std::cin >> s1; std::cin >> s2; int len1 = strlen(s1); int len2 = strlen(s2); //初始化第一列 for (int i = 0; i <= len1; ++i) { data[i][0] = i; } //初始化第一行 for (int j = 0; j <= len2; ++j) { data[0][j] = j; } int editDis = editDistance(s1, s2, len1, len2); std::cout << "最小的編輯距離是" << editDis << std::endl; return 0; }
4、執行結果
請輸入2個字串
family
frame
最小的編輯距離是4
5、總結
一般求最少的問題,最長的問題,我們一般看到最的問題就要想到動態規劃,然後找到遞推關係式
d [ i ][ j ] = min{ d [ i − 1][ j ] + 1, d [ i ][ j − 1] + 1, d [ i − 1][ j − 1] + diff ( i , j )}
這裡的時間複雜度和空間複雜度都是O(n* m),n是字串1的長度,m是字串2的長度。
相關推薦
動態規劃之編輯距離問題
由公式可以看出,(i-1,j)對應刪除操作,(i,j-1)對應插入操作。 可以這樣理解,現在耗費了di-1,j步操作將字串a(1,i-1)轉換成了b(1,j),則在將a(1,i)轉換成b(1,j)時,我們可以直接刪掉字元a(i), 問題變成a(1,i-1)轉換成b(1,j),從而dij就等於d
動態規劃之編輯距離:用最少的字元操作將A變換成B
一、問題描述 設A和B是兩個字串,長度分別為n,m要用最少的字元操作(包括字元的插入、刪除、修改),這樣的操作稱為字串A到B的操作距離,記為d(A,B)。 二、思路分析 把求解編輯距離分為字串A從0個字元逐漸增
動態規劃之編輯距離
1、問題例如兩個字串 FAMILY 和 FRAME ,有兩種對齊方式:1)、F_A MIL YFRAME2)、_FAMILYFRAME第 1 種對齊需要付出的代價: 4 ,插入 R ,將 I 替換為 E ,刪除 L 、 Y 。第 2 種對齊需要付出的代價: 5 ,插入 F,將
動態規劃-LeetCode72-編輯距離
題目 給定兩個單詞 word1 和 word2,計算出將 word1 轉換成 word2 所使用的最少運算元 。 你可以對一個單詞進行如下三種操作: 插入一個字元 刪除一個字元 替換一個字元 示例 1: 輸入: word1 = "horse", word2 = "ros" 輸出: 3 解釋
動態規劃求解編輯距離問題
題目描述: 要求兩字串有差異的字元個數。例如: aaaaabaaaaa aaaaacaabaa 這兩個字串,最大公共字串長度是5,但它們只有兩個字元不同,函式輸出值應為2。 如果是: aaabbbcccddd aaaeeeddd 函式的輸出值應該是6。 比較形象地形容一下,把
【1】【leetcode-72 動態規劃】 編輯距離
ade 均可 distance 刪除 new ret min sta 插入 (沒思路,很典型,重要) 給定兩個單詞 word1 和 word2,計算出將 word1 轉換成 word2 所使用的最少操作數 。 你可以對一個單詞進行如下三種操作: 插入一個字符 刪
[C++] 動態規劃之矩陣連乘、最長公共子序列、最大子段和、最長單調遞增子序列
每次 種子 () return 避免 amp 可能 text com 一、動態規劃的基本思想 動態規劃算法通常用於求解具有某種最優性質的問題。在這類問題中,可能會有許多可行解。每一個解都對應於一個值,我們希望找到具有最優值的解。 將待求解問題分解成若幹個子問題,先求
動態規劃之01背包問題(含代碼C)
bsp sys 最優解 ret 時間復雜度 維數 style 時間 沒有 1.動態規劃的基本思想 動態規劃算法通常用於求解具有某種最優性質的問題。其基本思想也是將待求解問題分解成若幹個子問題,先求解子問題,然後從這些子問題的解得到原問題的解。與分治法不同的是,適合於用動
LeetCode-動態規劃之Triangle
pre family add where throw to do 16px owin ext 題目描述 Given a triangle, find the minimum path sum from top to bottom. Each step you may mo
動態規劃之01背包詳解
題解 for 可見 round 往裏面 原創 ble -a eight 先看問題: 有N件物品和一個容量為V的背包。(每種物品均只有一件)第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入背包可使價值總和最大。 通過閱讀問題,因為背包就是要往裏面放東西,所以一件
動態規劃之完全背包詳解
現在 max 相同 維數 自己 一維數組 方法 table 得到 在昨天我已經很詳細的講解過01背包的動態規劃問題了,今天我講解的是完全背包的問題,這是01背包的詳解:http://www.cnblogs.com/Kalix/p/7617856.html 先看問題:在n種物
動態規劃之遞推求解
com 輸出 b站 eof sea 註意 des 不難 sca 動態規劃在B站上有個up主講得不錯,在此分享出來,如果對動態規劃還比較懵逼的可以先去看看。 https://www.bilibili.com/video/av16544031/?from=sea
動態規劃之最長遞增子序列(LIS)
lib sca while -c -o 組成 describe log ret 在一個已知的序列{ a1,a2,……am}中,取出若幹數組成新的序列{ ai1, ai2,…… aim},其中下標 i1,i2, ……im保持遞增,即新數列中的各個數之間依舊保持原
動態規劃之最長公共子序列(LCS)
int tdi -s can 數組下標 include har 遞推 最長公共子序列 在字符串S中按照其先後順序依次取出若幹個字符,並講它們排列成一個新的字符串,這個字符串就被稱為原字符串的子串 有兩個字符串S1和S2,求一個最長公共子串
動態規劃之背包問題實現php
動態規劃 背包問題php 最近在研究動態規劃算法,剛好看到背包問題。看到網上講解這方面問題很多,感覺都有點不明白,後面細思苦想好久,終於理解這個思路。於是寫下個人見解以及解題思路。背包問題描述如下:有編號分別為a,b,c,d,e的五件物品,它們的重量分別是4,2,6,5,3,它們的價值分別是6,3,5
動態規劃之最長公共子序列
圖片 輔助 length ret %s csp TP 子序列 輸出 原理請參考《算法導論》 定義常量 enum {upper_left, up, left}; #define LENGTHA (sizeof(A)/sizeof(A[0])) #define LENGTHB
POJ1742 coins 動態規劃之多重部分和問題
變形 價值 span 維數 text 推出 遞推 pro cal 原題鏈接:http://poj.org/problem?id=1742 題目大意:tony現在有n種硬幣,第i種硬幣的面值為A[i],數量為C[i]。現在tony要使用這些硬幣去買一塊價格不超過m的表。他希望
動態規劃之背包問題-01背包+完全背包+多重背包
自己 動態規劃 問題 動態 重復 -- 今天 code i++ 01背包 有n種不同的物品,每種物品分別有各自的體積 v[i],價值 w[i] 現給一個容量為V的背包,問這個背包最多可裝下多少價值的物品。 1 for(int i = 1; i <= n; i++)
DAG上的動態規劃之嵌套矩形問題
style printf 硬幣 介紹 == 矩形 n) clas 歸約 據說DAG是動態規劃的基礎,想一想還真的是這樣的,動態規劃的所有狀態和轉移都可以歸約成DAG DAG有兩個典型模型,一個是嵌套矩形問題一個是硬幣問題,這裏僅介紹一個嵌套矩形問題 等二輪復習的時候再補上
2018.8.17 題解 2018暑假集訓之編輯距離
msu type ring clu span 插入 pan -h 俄羅斯 應該是一個很經典的題目了吧 上題面描述 概念 字符串的編輯距離,又稱為Levenshtein距離,由俄羅斯的數學家Vladimir Levenshtein在1965年提出。是指利用字符操作,