最長公共子串行

2021-08-10 18:41:09 字數 1646 閱讀 6570

給你倆個字串,找公共最長的子串行串。

根據第乙個串的長度m,第二個串的長度n,建立乙個mxn的二維表。

這個表 dp [i][j] ,代表 第乙個串從 0 ~ i號下標和第二個串從0~j號下標這倆個字串的最長公共子串行。

那麼這個表的初始狀態是,dp[0][0]~dp[m-1][0]的值為,如果第乙個串的 i 號元素跟第二個串的0號元素相等則值為1否則值為0,但是如果dp[i-1][0]的值為1,那麼dp[i][0]的值也為1。因為i-1 是 i的字串,所以 i-1 有的公共字元在i中也一定有。對於dp[0][0]~dp[0][n-1]這個初始化跟上面這個類似。

那麼dp[i][j]的公式是這樣的,如果dp[i][j]可能有三種情況而來:

1.dp[i-1][j]來

2.dp[i][j-1]來

3.dp[i-1][j-1]來

那麼就很簡單了,分析下,dp[i-1][j]、dp[i][j-1]、dp[i-1][j-1]它們三個都相差乙個字元,其中dp[i-1][j-1]又是它們倆個的子串行。那麼它們的三個值如果相差最多差值為1。就在於這三個序列,乙個新增了乙個s1串的字元,乙個新增了s2串的乙個字元,乙個沒有新增。

那麼新增s1串的字元的子串行,可能因為新增後又有乙個公共子串行字元,那麼dp[i][j]應該選它。新增s2串的字元的子串行同理。

那麼可能,前面倆個新增後都沒有多公共子串行字元,那麼可能是第i個字元與第j個字元相等導致多了乙個公共子串行的字元,那麼這個時候dp[i][j]的值,就應該等於沒有新增字元的dp[i-1][j-1]的值加1了。

用**的思路就是,先從dp[i-1][j]與dp[i][j-1]中選個最大的,然後如果s1[i]==s2[j]的話,看dp[i-1][j-1]+1的值是否大於剛更新過的dp[i][j],如果大於重新更新下就ok。

#include

#include

#include

using

namespace

std;

void getdp(std::string&s1 ,std::string&s2,vector

>&ret)

for(int i=0;i0][i]=((s2[i]==s1[0]||(i>0&&ret[0][i]==1)))?1:0;

}for(int i=1;ifor(int j=1;j1][j]>ret[i][j-1])?ret[i-1][j]:ret[i][j-1];

if(s1[i]==s2[j]&&ret[i-1][j-1]+1>ret[i][j])

ret[i][j]=ret[i-1][j-1]+1;}}

}std::string getsub(std::string & s1 ,std::string & s2 )

getdp(s1,s2,dp);

int m =s1.size();

int n =s2.size();

std::string ret;

ret.resize(dp[m-1][n-1]);

int count = ret.size()-1;

int row = m-1;

int col = n-1;

while(count>=0)

}return ret;

}int main()

最長公共子串行 最長公共子串

1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...

最長公共子串行 最長公共子串

1.區別 找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而最長公共子串行則並不要求連續。2 最長公共子串 其實這是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧 bab 和 caba 當然我們現在一眼就可以看出來最長公...

最長公共子串 最長公共子串行

子串要求連續 子串行不要求連續 之前的做法是dp求子序列 include include include using namespace std const int inf 0x3f3f3f3f const int mod 1000000007 string s1,s2 int dp 1010 10...