問題描述
levenshtein 距離,又稱編輯距離,指的是兩個字串之間,由乙個轉換成另乙個所需的最少編輯操作次數。許可的編輯操作包括將乙個字元替換成另乙個字元,插入乙個字元,刪除乙個字元。編輯距離的演算法是首先由**科學家levenshtein提出的,故又叫levenshtein distance。
ex:字串a:abcdefg
字串b: abcdef
通過增加或是刪掉字元」g」的方式達到目的。這兩種方案都需要一次操作。把這個操作所需要的次數定義為兩個字串的距離。
要求:給定任意兩個字串,寫出乙個演算法計算它們的編輯距離。
解題思路
問題抽象:將a變為b所需的最少操作步數(也可以是b變為a的最少操作步數,兩個角度一樣。因為a變為b如果有插入的話,對應b變為a就可以等價為刪除;a變為b為替換的話,b變為a也可等價位替換;a變為b為刪除的話,b變為a等價為插入,因為步數都一樣)。用dp[x][y]表示a的前x個字元轉換為b的前y個字元所需要的最少操作步數
最優子結構:a的前x個字元變為b的前y個字元所需要的最少操作步數d[x][y]取決於子問題:
1)a的最後一位參與變換:
if(a的第x個字元不等於b的第y個字元)dp[x][y]=dp[x-1][y-1]+1 //將a的前x-1個字元變為b的前y-1個字元, 然後將最後乙個字元替換成b的最後乙個字元(一步)
else dp[x][y]=dp[x-1][y-1] //如果a的最後乙個字元等於b的最後乙個字元,則a的前x個字元變為b的前y個字元等價於將a的前x-1個字元變為b的前y-1個字元
2)a的最後一位不參與變換(刪除掉a的最後一位)
dp[x][y]=dp[x-1][y]+1 //將a的前x-1個字元變為b,然後將最後乙個字元刪除
3)b的最後一位不參與變化(刪除掉b的最後一位)
dp[x][y]=dp[x][y-1]+1 //將b的前y-1個字元變為a,然後將最後乙個字元刪除
dp[x][y]=min
當x=0時,即a為空字串,則a變為b的前y個字元所需的操作為y,dp[0][y]=y;
同理,y=0時,dp[x][0]=x;
這樣自底向上就能求出將a變為b最少的操作步數dp[a.length][b.length].
動態規劃的關鍵一步就是如何就將問題與子問題聯絡起來,即將問題i想辦法用問題i-1表示
#includeusing namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
int dp[1005][1005];
int main()
for(int i = 0;i <= len2;++i)
for(int i = 1;i <= len1;++i)else
dp[i][j] = min(dp[i][j],dp[i - 1][j] + 1);
dp[i][j] = min(dp[i][j],dp[i][j - 1] + 1);}}
cout << dp[len1][len2] << endl;
}return 0;
}
華為機試整理
include stdafx.h includeusing namespace std int main int argc,tchar argv cout 2.大數相加 用stl的string比較方便,如下,自己測了幾組資料沒有什麼問題。include stdafx.h include includ...
華為機試 2013
1.字串轉換 問題描述 將輸入的字串 字串僅包含小寫字母 a 到 z 按照如下規則,迴圈轉換後輸出 a b,b c,y z,z a 若輸入的字串連續出現兩個字母相同時,後乙個字母需要連續轉換2次。例如 aa 轉換為 bc,zz 轉換為 ab 當連續相同字母超過兩個時,第三個出現的字母按第一次出現算。...
華為機試3
明明想在學校中請一些同學一起做一項問卷調查,為了實驗的客觀性,他先用計算機生成了n個1到1000之間的隨機整數 n 1000 對於其中重複的數字,只保留乙個,把其餘相同的數去掉,不同的數對應著不同的學生的學號。然後再把這些數從小到大排序,按照排好的順序去找同學做調查。請你協助明明完成 去重 與 排序...