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

2021-06-27 00:56:29 字數 4115 閱讀 3120

題目要求:

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

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

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

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

題目分析:

**實現:

#include %26lt;iostream%26gt;

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] %26gt;= 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] = ;

intb[maxlen][maxlen];

intc[maxlen][maxlen];

intm, n;

m =strlen(x);

n =strlen(y);

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

printlcs(b, x, m, n);

cout %26lt;%26lt; "

最長公共子串行長度為:

" %26lt;%26lt; step %26lt;%26lt;endl;

cout %26lt;%26lt; "

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

for(int i = 0;i%26lt;step;i++)

cout %26lt;%26lt;store[i];

cout %26lt;%26lt;endl;

return0;

}

%26nbsp;

擴充套件問題1:

如果要列印所有最長公共子串,怎麼辦?

參看**實現中的pt函式,嘗試遍歷每一種情況,當達到最長公共子串行的長度時,就輸出。

**實現:

#include %26lt;iostream%26gt;#include %26lt;queue%26gt;

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] %26gt;= c[i][j-1

])

else}}

}void pt(char *x,char *y,deque%26lt; int%26gt; %26amp;que,int istart,int iend,int jstart, int jend,int

lcslen)

char tmp = -1

;

for(int i = istart;i%26lt;iend;i++)}}

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

;

char y[maxlen+1] = ;

int c[maxlen+1][maxlen+1

];

intm, n;

m =strlen(x);

n =strlen(y);

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

deque%26lt; int%26gt;que;

pt(x,y,que,

0,m,0

,n,c[m][n]);

return0;

}

%26nbsp;

擴充套件問題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

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

#include %26lt;iostream%26gt;#include %26lt;cstring%26gt;

using

namespace

std;

int lcs(const

char *str1 , int len1 , const

char *str2 , int len2 , char *%26amp;lcs)

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

int *c = new

int[len2+1

];

for(int i = 0 ; i %26lt; len2 ; ++i)

int max_len = 0; //

匹配的長度

int pos = 0; //

在 str2上的匹配最末位置

for(int i = 0 ; i %26lt; len1 ; ++i)

}else}}

if(0 ==max_len)

//得到公共子串

lcs = new

char

[max_len];

for(int i = 0 ; i %26lt; max_len ; ++i)

cout%26lt;%26lt; "

pos =

"%26lt;%26lt;pos%26lt;%26lt;endl;

delete c;

return

max_len;

}int

main()

}

%26nbsp;

%26nbsp;

%26nbsp;

最長公共子串行 微軟面試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 當然我們現在一眼就可以看出來最長公...