什麼是最長公共子序列呢?比如一個數列 S,若是分別是兩個或多個已知數列的子序列,且是全部符合此條件序列中最長的,則S 稱爲已知序列的最長公共子序列。html
舉個例子,如:有兩條隨機序列,如 1 3 4 5 5 ,and 2 4 5 5 7 6,則它們的最長公共子序列即是:4 5 5。ios
注意:【最長公共子串(Longest CommonSubstring)和最長公共子序列(LongestCommon Subsequence, LCS)的區別】算法
子串(Substring)是串的一個連續的部分,子序列(Subsequence)則是從不改變序列的順序,而從序列中去掉任意的元素 而得到的新序列;更簡略地說,前者(子串)的字符的位置必須連續,後者(子序列LCS)則沒必要。好比字符串acdfg同akdfc的最長公共子串爲df, 而他們的最長公共子序列是adf。LCS可使用動態規劃法解決。下文具體描述。優化
(靠蠻力啊。。。)spa
用動態規劃法首先要判斷該問題是否符合動態規劃法的條件。時間複雜度O(n^2)。code
(1) 最優化原理:若是問題的最優解所包含的子問題的解也是最優的,就稱該問題具備最優子結構,即知足最優化原理。htm
(2) 無後效性:即某階段狀態一旦肯定,就不受這個狀態之後決策的影響。也就是說,某狀態之後的過程不會影響之前的狀態,只與當前狀態有關。blog
(3) 有重疊子問題:即子問題之間是不獨立的,一個子問題在下一階段決策中可能被屢次使用到。(該性質並非動態規劃適用的必要條件,可是若是沒有這條性質,動態規劃算法同其餘算法相比就不具有優點)字符串
// LCSTest.cpp : 定義控制檯應用程序的入口點。 #include "stdafx.h" #include<iostream> #include<cstdlib> #include<string> #include<vector> using namespace std; void LCS(string str1,string str2) { int len1 = str1.length(); int len2 = str2.length(); //int **dp = new int[len1+1][len2+1]; vector<vector<int> > dp(len1+1,vector<int>(len2+1)); //動態規劃初始值 for(int j = 0;j <= len2;j++) dp[0][j] = 0; for(int i = 0;i <=len1;i++) dp[i][0] = 0; for(int i = 0;i < len1;i++) for(int j = 0;j < len2;j++) { if(str1.at(i) == str2.at(j)) { dp[i+1][j+1]= dp[i][j]+1; } else if(dp[i][j+1] > dp[i+1][j]) dp[i+1][j+1] = dp[i][j+1]; else dp[i+1][j+1] = dp[i+1][j]; } cout<<"最長公共子序列長度爲:"<<dp[len1][len2]<<endl; int ti = 0; int tj = 0; while(ti<len1 && tj<len2 ) { if(str1.at(ti) == str2.at(tj)) { cout<<str1.at(ti)<<" "; ti++; tj++; } else if(dp[ti+1][tj] >= dp[ti][tj+1]) ti++; else tj++; } } int _tmain(int argc, _TCHAR* argv[]) { string str1 = "asddgflsksdjflkdf"; string str2 = "sdflsdzf"; LCS(str1,str2); return 0; }