最長公共子串行 微軟面試100題 第五十六題

2021-06-26 23:11:12 字數 3741 閱讀 7662

題目要求:

如果字串一的所有字元按其在字串中的順序出現在另外乙個字串中,則字串一稱為字串二的子串。

注意,並不是要求子串(字串一)的字元必須連續出現在字串二中。

請編寫乙個函式,輸入兩個字串,求它們的最長公共子串行,並列印出最長公共序列。

例如:輸入兩個字串bdcaba和abcbdab,字串bcba、bdab和bcab都是它們的最長公共子串行,則輸出它們的長度4,並列印任意乙個子串行。

題目分析:

**實現:

#include using

namespace std;

#define maxlen 100

void lcslength(char *x, char *y, int m, int n, int c[maxlen], int b[maxlen])

else

if(c[i-1][j] >= c[i][j-1])

else}}

}char store[maxlen] = ;

int step = 0;

void printlcs(int b[maxlen], char *x, int i, int j)

else

if(b[i][j] == 1)

printlcs(b, x, i-1, j);

else

printlcs(b, x, i, j-1);

}int main(int argc, char **argv)

; char y[maxlen] = ;

int b[maxlen][maxlen];

int c[maxlen][maxlen];

int m, n;

m = strlen(x);

n = strlen(y);

lcslength(x, y, m, n, c, b);

printlcs(b, x, m, n);

cout << "

最長公共子串行長度為:

"<< step << endl;

cout << "

其中乙個最長公共子串行為:

"; for(int i = 0;ireturn

0;}

擴充套件問題1:如果要列印所有最長公共子串,怎麼辦?參看**實現中的pt函式,嘗試遍歷每一種情況,當達到最長公共子串行的長度時,就輸出。

**實現:

#include #include using

namespace std;

#define maxlen 100

void lcslength(char *x, char *y, int m, int n, int c[maxlen+1])

else

if (c[i-1][j] >= c[i][j-1])

else}}

}void pt(char *x,char *y,deque< int> &que,int istart,int iend,int jstart, int jend,int lcslen)

char tmp = -1;

for(int i = istart;i1;

for(int j = jstart;jif(x[i]==y[j] && x[i]!=tmp)}}

}int main(int argc, char **argv)

; char y[maxlen+1] = ;

int c[maxlen+1][maxlen+1];

int m, n;

m = strlen(x);

n = strlen(y);

lcslength(x, y, m, n, c);

deque< int> que;

pt(x,y,que,0,m,0,n,c[m][n]);

return

0;}

擴充套件問題2:最長公共子串,這個子串要求在原字串中是連續的。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧:"bab"和"caba"(當然我們現在一眼就可以看出來最長公共子串是"ba"或"ab")

b  a  b

c  0  0  0

a  0  1  0

b  1  0  1

a  0  1  0

我們看矩陣的斜對角線最長的那個就能找出最長公共子串。

不過在二維矩陣上找最長的由1組成的斜對角線也是件麻煩費時的事,下面改進:當要在矩陣是填1時讓它等於其左上角元素加1。

b  a  b

c  0  0  0

a  0  1  0

b  1  0  2

a  0  2  0

這樣矩陣中的最大元素就是最長公共子串的長度。

  **講解:沒有申請二維陣列,申請的是串1長度

的乙個一維數

組。每次求一行,然後後面一行用到前面一行的資料。

//壓縮後的最長子串記錄向量

int *c = new

int[len2+1];

for(int i = 0 ; i < len2 ; ++i)

int max_len = 0; //

匹配的長度

int pos = 0; //

在 str2上的匹配最末位置

for(int i = 0 ; i < len1 ; ++i)

}else}}

if(0 == max_len)

//得到公共子串

lcs = new

char [max_len];

for(int i = 0 ; i < max_len ; ++i)

cout<< "

pos =

"}int main()

}

最長公共子串行 微軟面試100題 第五十六題

題目要求 如果字串一的所有字元按其在字串中的順序出現在另外乙個字串中,則字串一稱為字串二的子串。注意,並不是要求子串 字串一 的字元必須連續出現在字串二中。請編寫乙個函式,輸入兩個字串,求它們的最長公共子串行,並列印出最長公共序列。例如 輸入兩個字串bdcaba和abcbdab,字串bcba bda...

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

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 當然我們現在一眼就可以看出來最長公...