经典:题给出两个字符串(可能包含空格),找出其中最长的公共连续子串,输出其长度。
第一反应一定是动态规划,那么需要注意以下几点:
1. 如果其中一个为空串或者都为空串,结果为0
if(len1==0 || len2==0)
return 0;
2. 输入中可能包含空格,空格也将作为一个字符进行比较
我经常用经典的输入输出流,cin遇到回车和空格均当作字符串的结束,因此,处理方式如下:
//包含头文件 #include <string.h> #include <cstdio> //将字符串定义为char数组 char s1[50],s2[50]; //输入时,采用cin.getline(str,maxinum) cin.getline(s1,50); cin.getline(s2,50);
3. 申请二维数组是,第一,采用vector容器实现,第二,采用动态申请空间实现,我用的第二种
int len1=strlen(s1);
int len2=strlen(s2);
int max=-1;
if(len1==0 || len2==0)
return 0;
int **a = new int *[len1+1]; //先动态申请行
int i,j;
for(i=0;i<=len1; ++i)
{
a[i] = new int [len2+1]; //在动态申请列;p[i]的类型是int* 即整型指针;
}
4. 填充数组是关键,当其中一个为空串是,结果一定为0,因此,第一行和第一列,均为0
for(i=0;i<=len1;i++)
{
a[i][0]=0; //s1为空串
}
for(j=0;j<=len2;j++)
{
a[0][j]=0; //s2为空串
}
5. 其余部分,根据一直部分进行填充,由于本题为连续字符串,因此,填充时,仅需根据左上角元素进行填充,并且,随时更新二维矩阵中的最大值
//填充其余数组
for(i=1;i<=len1;i++)
{
for(j=1;j<=len2;j++)
{
if(s1[i-1]==s2[j-1])
{
a[i][j]=a[i-1][j-1]+1;
}else{
a[i][j]=0;
}
if(a[i][j]>max)
max=a[i][j];
}
}
6. 最大值max即为最大公共子串长度。
1 #include <iostream>
2 #include <string.h>
3 #include <cstdio>
4 #include <vector>
5 using namespace std;
6 char s1[50],s2[50];
7 int ML(char* s1,char* s2)
8 {
9 int len1=strlen(s1);
10 int len2=strlen(s2);
11 int max=-1;
12 if(len1==0 || len2==0)
13 return 0;
14 int **a = new int *[len1+1]; //先动态申请行
15 int i,j;
16 for(i=0;i<=len1; ++i)
17 {
18 a[i] = new int [len2+1]; //在动态申请列;p[i]的类型是int* 即整型指针;
19 }
20
21 for(i=0;i<=len1;i++)
22 {
23 a[i][0]=0; //s1为空串
24 }
25 for(j=0;j<=len2;j++)
26 {
27 a[0][j]=0; //s2为空串
28 }
29 //填充其余数组
30 for(i=1;i<=len1;i++)
31 {
32 for(j=1;j<=len2;j++)
33 {
34 if(s1[i-1]==s2[j-1])
35 {
36 a[i][j]=a[i-1][j-1]+1;
37 }else{
38 a[i][j]=0;
39 }
40 if(a[i][j]>max)
41 max=a[i][j];
42 }
43 }
44 for(i=0;i<=len1;i++)
45 {
46 for(j=0;j<=len2;j++)
47 {
48 cout<<a[i][j]<<" ";
49 }
50 cout<<endl;
51 }
52 return max;
53
54 }
55 int main()
56 {
57 cin.getline(s1,50);
58 cin.getline(s2,50);
59 cout<<ML(s1,s2)<<endl;
60 return 0;
61 }