字符串处理算法(六)求2个字符串最长公共部分

如题,求2个字符串最长公共部分。

方法一:

2个循环,遍历2个字符串,这里记得要回溯,2个字符串都要有,否则,找不出来正确的结果。

实现代码如下:

int main()
{
	char a[80],b[80],c[80],d[500][80]; 
	memset(c, 0, 80);
	int i,j,m,n,t,k; 
	gets(a); 
	gets(b);//输入字符串 
	puts(a); 
	puts(b);//输出字符串 
	m=strlen(a); 
	n=strlen(b);//计算字符串实际长度 

	int nFlag = 0;
	k = 0;
	int nTemp = 0;
	
	for(i=0;i<m;i++)    
	{
		nFlag = 0;
		t=0; 
		nTemp = i;
		for(j=0;j<n;j++)    
		{        
			if(a[i]==b[j])        
			{      
				nFlag = 1;           
				c[t]=a[i];            
				t=t+1;           
				i=i+1;            
				//j=j+1;        
			}//寻找字符串公共部分并赋值给c 
			else 
			{
				if (nFlag == 1)
				{
					strcpy(d[k++], c);
					memset(c, 0, 80);
					nFlag = 0;
					t=0;
					i = nTemp;
					j=j-1;
				}
				
			}
		}//把公共部分放入d[i]中  
		if (nFlag == 1)
		{
			strcpy(d[k++], c);
			memset(c, 0, 80);
			i = nTemp;
		}
	}
	strcpy(c,d[0]);//把d中第一行赋值给c 
	for(i=1;i<k-1;i++)    
	{       
		if(strlen(c)<strlen(d[i]))            
			strcpy(c,d[i]);//如果d[i]字符串长度比c长就把d[i]中的字符串复制给c    
	}    
	puts(c); 
	return 0; 
}

测试用例:

1.abcdef,efhabc

2.abcdef,aefhabc

3.abcdef,ababc

用例1是不需要回溯就可以的,用例2说明了需要对数组1回溯,用例3说明需要对数组2回溯。算法是一个逐渐完善的过程,需要对不同的情况测试,才能找出隐患和问题。通过不断的积累,就可以开始的时候,尽量全的考虑一些用例,而存在的隐患就会少。

可以改进的地方:

1.可以用string、vector来代替字符串和数组。

2.可以只用一个d[],而不是d[][],判断c,d的长度,当strlen(c)>strlen(d),则strcpy(d,c)。

//20131025

当数组1是bbc,数组2是bbbc时候,算法有问题。

更改:

j=j-1;改成j=j-strlen(c);

如果用string就是找到数组1的首字母在b中出现的位置,并记住,下次再从这里开始查找,第一次当然是从0开始了。

方法二(来自网上):

//最长公共子序列字符个数 
//c[i][j]保存字符串 {xi},{yj},(长度分别为i,j)的最长公共子序列的字符个数 
//i=0或者是j=0 时,c[i][j]必定为零, i,j>=0 且 xi=yj, c[i][j]=c[i-1][j-1]+1 
//若 i,j>0 但xi!=yj, c[i][j]=max{ c[i-1][j] , c[i][j-1] } 
#include <stdio.h> 
#include <string.h> 
int c[1001][1001]; 
void lcs(int a, int b, char x[], char y[], int c[][1001]) 
{     
    int i,j;     
    for(i=1;i<a;i++)         
        c[i][0]=0; //if b==0, set c[i][j]=0;     
    for(i=1;i<b;i++)         
        c[0][i]=0; // if a==0; set c[i][j]=0;     
    for(i=1;i<=a;i++) // if a!=0,b!=0 loop         
        for(j=1;j<=b;j++) 
        {             
            if(x[i-1]==y[j-1])                 
                c[i][j]=c[i-1][j-1]+1;             
            else if (c[i-1][j]>=c[i][j-1])                 
                c[i][j]=c[i-1][j];             
            else                
                c[i][j]=c[i][j-1];         
         } 
} 

int main() 
{     
    char x[1001],y[1001];     
    while ( scanf("%s%s",x,y)!=EOF ) 
    {         
        int a=strlen(x);         
        int b=strlen(y);         
        memset(c,0,sizeof(c));
        lcs(a,b,x,y,c);
        printf("%d\n",c[a][b]);
    }
    
    return 0; 
}


printf("%d\n",c[a][b]);,这里应该是c[a+1][b+1]。



转载请注明原创链接:http://blog.csdn.net/wujunokay/article/details/13002251

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值