给定两个字符串,求最大公共字串的长度

来源于> https://blog.csdn.net/SupreV/article/details/78627945

思路:
输入两个字符串,由短字符串的长度决定比较次数。
每次比较一个字符,从短字符串的第一个依次与长字符串的每一个字符比较,若出现相同的字符,则两个字符串各自取下一位进行比较,直到出现不相同字符的为止。(同时要注意比较是不能超出短字符串的长度,不然会出现未知后果)
定义两个数组a,b;a用来获取相同字符,若a的长度大于b的长度,则将a复制给b。

#include <stdio.h>
#include <string.h>
void substr(char *s1, char *s2, int len){
    int i, j, m = 0;
    int p, q;
    int length = strlen(s2);
    char a[100] = {0};
    char b[100] = {0};
    for(i = 0; i < len; i++){
        for(j = 0; j < length; j++){
            strcpy(a, "0");
            p = i;
            q = j;
            while(s1[p] == s2[q] && s1[p] != 0){
                a[m] = s2[q];
                p++;
                q++;
                m++;
            }
            if(strlen(a) > strlen(b)){
                strcpy(b, a);
            }
            m = 0;
        }
    }
    printf("最大公子串:%s\n", b);
}
int main(){
    char str1[100] = {0};
    char str2[100] = {0};
    int len;
    printf("请输入字符串1:");
    scanf("%s", str1);
    printf("请输入字符串2:");
    scanf("%s", str2);
    len = strlen(str1) <= strlen(str2) ? strlen(str1) : strlen(str2);
    if(len == strlen(str1)){
        substr(str1, str2, len);    
    }
    else if(len == strlen(str2)){
        substr(str2, str1, len);
    }
    return 0;
}

方法2:暴力解法

将字符串s1和s2分别写在两把直尺上面,然后将s1固定,s2的头部和s1的尾部对齐,然后逐渐移动直尺s2,比较重叠部分的字符串中的公共子串的长度,直到直尺s2移动到s1的头部。在这个过程中求得的最大长度就是s1、s2最大子串的长度。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
char* longest_common_substring(char *str1,char *str2)
{
	int str1len = strlen(str1);
	int str2len = strlen(str2);
	int i,j,index,max=0,num=0; 
	int start;
    
	//将两个字符串看做两个直尺,固定一个直尺,另外一个从头到尾开始移动,逐一与固定的直尺比较值。
	for(i = 0; i < str1len; i++) 
	{
		for(j = 0; j < str2len; j++)
		{
			//这里的start1、start2是比较关键的
			int start1=i;
			int start2=j;
			while((start1 <= str1len-1) && (start2 <= str2len-1) && (str1[start1++] == str2[start2++]))
				num++;
			if(num > max)//如果num是当前最大匹配的个数,则赋给max,并且在start记下str1最长匹配开始的位置
			{
				max=num;
				start=i; 
			} 
			num=0;//如果num不是当前最大的,则赋为0值继续循环
		}
	}
	char *str=(char *)malloc(max + 1);
	strncpy(str,str1 + start,max);//从字符串str1的start位置开始,拷贝max个字符到str中,这就是我们找出的最大子串
	str[max] = '\0';
	printf("最长公共连续子串的长度为:%d\n",max);
	return str;
}
 
int main()
{ 
	char str1[1000],str2[1000];
	printf("请输入第一个字符串:");
	gets(str1);
	printf("请输入第二个字符串:");
	gets(str2);
 
	char *str= longest_common_substring(str1,str2);
	printf("%s\n",str);
	free(str);  //记得要free,否则造成内存泄露
	system("pause");
	return 0;    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值