C实践习题集2之最长公共子串
最长公共子串
题目
给定两个字符串a、b,现有k次机会对字符串中的字符进行修改,使修改后两个字符串的最长公共子串最长。每一次修改,可以选择a、b字符串中某一个串的任意位置修改成任意字符。
输入格式:
第一行包括一个正整数 k。
第二行和第三行分别输入字符串a、b。(每个串的长度不超过500)
输出格式:
输出为一个整数,表示修改后的两个串的最长公共子串长度。
输入样例:
5
aaaaa
bbbbb
输出样例:
5
思路
这题我题意理解错了,刚开始一直以为最长公共子串一定要是相同字母组成,比如
k=3 我以为需要把两个字符串转化为 此时最大长度为4 其实,转化为 最大长度为4 是这么得来的
str1:abaad str1:aaaad str1: abaad
str2:cabba str2:caaaa str2:cabaaa
我在网上找方法时,看到了这位的题解,直接用暴力判(很直接,我喜欢(此句删去))
不过这位的代码有的地方的操作我没看懂,比如一二重循环i和j分别都是从1开始,然后在判断时又减一,以达到遍历效果
不过核心解法我已经get到了啦
下面是完整代码
#include<stdio.h>
#include<string.h>
int Max(int a,int b);
int main()
{
int k,i,j,max=-1,p1,p2,store,limit;
char s1[505],s2[505];
scanf("%d",&k);
scanf("%s",s1);
scanf("%s",s2);
for(i=0;s1[i]!='\0';i++){//在s1字符串上选一个起点
for(j=0;s2[j]!='\0';j++){//在s2字符串上选一个起点
p1=i;
p2=j;
limit=k;
store=0;//记录s1起点和s2起点的不同组合下,所能得到的公共子串长度,需要清零
while(s1[p1]!='\0'&&s2[p2]!='\0'){//越界时结束循环
while(s1[p1]!='\0'&&s2[p2]!='\0'&&s1[p1]==s2[p2]){
//首先判断是否越界,接着是检查s1[p1],s2[p2]这两点是否相同,满足则进入循环
p1++;//把s1上检索的点往后推
p2++;//s2上的也是
store++;//记录的长度+1
}
max=Max(store,max);//对比max(历史最大长度)和当前长度,选取大的那个
if(limit&&s1[p1]!='\0'&&s2[p2]!='\0'){
//次数不为0且未出现越界情况时,进入循环,修改字符(不用管具体怎么改,最后的长度都一样)
p1++;
p2++;
store++;
limit--;//次数减一
max=Max(store,max);//取大的那个
}
else break;
}
}
}
printf("%d",max);
return 0;
}
int Max(int a,int b)
{
if(a>b) return a;
else return b;
}