1.求最长公共子串长度:
(1)正常求:
<span style="font-size:14px;">int lcs(int l1,int l2){
memset(maxlen,0,sizeof(maxlen));
for(int i=1;i<=l1;i++){
for(int j=1;j<=l2;j++){
if(str1[i-1]==str2[j-1])
maxlen[i][j]=maxlen[i-1][j-1]+1;
else if(maxlen[i-1][j]>maxlen[i][j-1])
maxlen[i][j]=maxlen[i-1][j];
else maxlen[i][j]=maxlen[i][j-1];
}
}
}
</span>
(2) 节省记忆空间:
maxlen[2][Max+10] 节省记忆空间
<span style="font-size:14px;">int maxlen[2][Max+10];
int lcs(int len1,int len2){
memset(maxlen,0,sizeof(maxlen));
for(int i=1;i<=len1;i++){
for(int j=1;j<=len2;j++){
if(str1[i-1]==str2[j-1])
maxlen[i%2][j]=maxlen[(i-1)%2][j-1]+1;
else if(maxlen[(i-1)%2][j]>maxlen[i%2][j-1])
maxlen[i%2][j]=maxlen[(i-1)%2][j];
else maxlen[i%2][j]=maxlen[i%2][j-1];
}
}
}
printf("%d\n",maxlen[len1%2][len2]);</span>
用maxlen[Maxlen] 及 t[Max+10]; // t[Max+10] 用来记录左上方的值;
<span style="font-size:14px;">int lcs(int l1,int l2){
memset(maxlen,0,sizeof(maxlen))
for(int i=1;i<=l1;i++){
for(int j=1;j<=l2;j++){
if(str1[i-1]==str2[j-1]){
t[j]=maxlen[j];
maxlen[j]=t[j-1]+1;
}
else if(maxlen[j-1]>maxlen[j]){
t[j]=maxlen[j];
maxlen[j]=maxlen[j-1];
}
else{
t[j]=maxlen[j];
maxlen[j]=maxlen[j];
}
}
}
}</span>
用maxlen[Maxlen] 及 变量t 变量leftup;
<span style="font-size:14px;">int lcs(int l1,int l2){
memset(maxlen,0,sizeof(maxlen));
int leftup;
for(int i=1;i<=l1;i++){
leftup=0;
for(int j=1;j<=l2;j++){
if(str1[i-1]==str2[j-1]){
int t=maxlen[j];
maxlen[j]=leftup+1;
leftup=t;
}
else if(maxlen[j-1]>maxlen[j]){
int t=maxlen[j];
maxlen[j]=maxlen[j-1];
leftup=t;
}
else{
int t=maxlen[j];
maxlen[j]=maxlen[j];
leftup=t;
}
}
}
}</span>
2.输出最长公共子串
(1)递归输出
正常输出:
<span style="font-size:14px;">void print(int i,int j){
if(i==0||j==0)
return;
else if(str1[i-1]==str2[j-1]){
print(i-1,j-1);
printf("%c",str1[i-1]);
}
else if(maxlen[i][j]==maxlen[i-1][j])
print(i-1,j);
else if(maxlen[i][j]==maxlen[i][j-1])
print(i,j-1);
}</span>
用数组p[Max+10][Max+10] 记录每一格是由哪一格而来
<span style="font-size:14px;">void print(int i,int j){
if(i==0||j==0)
return;
else if(p[i][j]==1){
print(i-1,j-1);
printf("%c",str1[i-1]);
}
else if(p[i][j]==2)
print(i-1,j);
else if(p[i][j]==3)
print(i,j-1);
}
//对应lcs函数
int lcs(int l1,int l2){
memset(maxlen,0,sizeof(memset));
for(int i=1;i<=l1;i++){
for(int j=1;j<=l2;j++){
if(str1[i-1]==str2[j-1]){
maxlen[i][j]=maxlen[i-1][j-1]+1;
p[i][j]=1;
}
else if(maxlen[i-1][j]>maxlen[i][j-1]){
maxlen[i][j]=maxlen[i-1][j];
p[i][j]=2;
}
else{
maxlen[i][j]=maxlen[i][j-1];
p[i][j]=3;
}
}
}
}</span>
(2) 非递归输出:
<span style="font-size:14px;">void print(){
int k=0;
int i=strlen(str1);
int j=strlen(str2);
int lcs[Max+10];
while(i>0&&j>0){
if(p[i][j]==1){
lcs[k++]=str1[i-1];
i--;
j--;
}
else if(p[i][j]==2)
i--;
else if(p[i][j]==3)
j--;
}
for(int h=k-1;h>=0;h--)
printf("%c",lcs[h]);
}</span>
在这个过程中也同样可以不使用数组p[Max+10][Max+10];