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;
}
posted @ 2020-03-03 12:42  枭魈  阅读(560)  评论(0编辑  收藏  举报