原理:x軸とy軸はそれぞれ自分自身とstr2を取り、テーブルは整列されます。
同じ文字が1に設定され、もう1つが0に設定され、対角線が使用されます。0以外の最長の文字列は、一般的な部分文字列です。
たとえば、asbbefgとaubegの最大値は2です。
A | s | b | b | e | f | g | |
A | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
u | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
b | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
e | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
g | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
ゼロ以外の最長の対角線に対応するセルは「be」であるため、「be」が最長の共通部分文字列であることがわかります。
アルゴリズムは最適化できます。
テーブルに値を割り当てる場合、str1 [i] == str2 [j]の場合; comparetbl [i] [j] = comparetbl [i-1] [j-1] +1
A | s | b | b | e | f | g | |
A | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
u | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
b | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
e | 0 | 0 | 0 | 0 | 2 | 0 | 0 |
g | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
inline SString SString::maxCommonSubstr(SString &str2) {
//原理: 动态规划 x 轴和 y 轴分别取 自身和str2
//然后表格对齐,相同的字符 设成 1 其他为 0 ,取斜对角线最长不为0
//asbbefg 和 aubeg 最大值2
/*
a s b b e f g
a 1 0 0 0 0 0 0
u 0 0 0 0 0 0 0
b 0 0 1 1 0 0 0
e 0 0 0 0 2 0 0
g 0 0 0 0 0 0 1
*/
int len1 = this->length();
int len2 = str2.length();
if (len1 ==0 || len2 == 0 ){
return SString();
}
int maxlen=-1; //最大长度
int lastIndex =-1; //最大值在主串的位置
int comparetbl[len2][len1];
for (int i = 0; i <len2 ; ++i) {
char modelchar=str2[i];
for (int j = 0; j < len1; ++j) {
if (str_[j]==modelchar){
if (i<1 || j<1 ){
comparetbl[i][j]=1;
}else{
comparetbl[i][j]=1+comparetbl[i-1][j-1];
}
} else{
comparetbl[i][j]=0;
}
if (maxlen<comparetbl[i][j]){
maxlen=comparetbl[i][j];
lastIndex = j;
}
}
}
SString ret = this->subString(lastIndex-maxlen+1,maxlen);
return ret;
}