題目要求:
如果字串一的所有字元按其在字串中的順序出現在另外乙個字串中,則字串一稱為字串二的子串。
注意,並不是要求子串(字串一)的字元必須連續出現在字串二中。
請編寫乙個函式,輸入兩個字串,求它們的最長公共子串行,並列印出最長公共序列。
例如:輸入兩個字串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 當然我們現在一眼就可以看出來最長公...