您的位置:首页 > 其它

查找两个字符串a,b中的最长公共子串

2017-06-14 11:23 323 查看
//方法一:时间复杂度O(n3),空间复杂度O(n)

#include<bits/stdc++.h>
using namespace std;
int main()
{
string a,b;
while(cin>>a>>b)
{
string t;
if(a.size()>b.size())
{
t=a;
a=b;
b=t;
}
cout<<endl<<endl;
cout<<a<<endl<<b<<endl;
int Max=0;
for(int i=0; i<a.size(); i++)
{
for(int j=0; j<b.size(); j++)
{
int num=0;
for(int k=0; k+i<a.size()&&k+j<b.size(); k++)
{
if(a[k+i]!=b[k+j])break;
else num++;
}
if(num>Max)Max=num;
}
}
int flag=1;
for(int i=0; i<a.size()&&flag; i++)
{
for(int j=0; j<b.size(); j++)
{
int num=0;
for(int k=0; k+i<a.size()&&k+j<b.size(); k++)
{
if(a[k+i]!=b[k+j])break;
else num++;
}
if(num==Max)
{
cout<<num<<endl;
flag=0;
cout<<a.substr(i,num)<<endl;
break;
}
}
}
}
return 0;
}

//方法二:时间复杂度O(n2),空间复杂度O(n2)

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
int longest_common_substring(char *str1, char *str2)
{
int i,j,k,len1,len2,max,x,y;
len1 = strlen(str1);
len2 = strlen(str2);
int **c = new int*[len1+1];
for(i = 0; i < len1+1; i++)
c[i] = new int[len2+1];
for(i = 0; i < len1+1; i++)
c[i][0]=0;        //第0列都初始化为0
for(j = 0; j < len2+1; j++)
c[0][j]=0;        //第0行都初始化为0
max = -1;
for(i = 1 ; i < len1+1 ; i++)
{
for(j = 1; j < len2+1; j++)
{
if(str1[i-1]==str2[j-1])     //只需要跟左上方的c[i-1][j-1]比较就可以了
c[i][j]=c[i-1][j-1]+1;
else                         //不连续的时候还要跟左边的c[i][j-1]、上边的c[i-1][j]值比较,这里不需要
c[i][j]=0;
if(c[i][j]>max)
{
max=c[i][j];
x=i;
y=j;
}
}
}
//输出公共子串
char s[1000];
k=max;
i=x-1,j=y-1;
s[k--]='\0';
while(i>=0 && j>=0)
{
if(str1[i]==str2[j])
{
s[k--]=str1[i];
i--;
j--;
}
else       //只要有一个不相等,就说明相等的公共字符断了,不连续了
break;
}
printf("最长公共子串为:");
puts(s);
for(i = 0; i < len1+1; i++)         //释放动态申请的二维数组
delete[] c[i];
delete[] c;
return max;
}
int main(void)
{
char str1[1000],str2[1000];
printf("请输入第一个字符串:");
gets(str1);
printf("请输入第二个字符串:");
gets(str2);
int len = longest_common_substring(str1, str2);
printf("最长公共连续子串的长度为:%d\n",len);
system("pause");
return 0;
}

//方法三:时间复杂度O(n2),空间复杂度O(n)
#include <iostream>
#include <cstring>
using namespace std;
//    查找公共子串
//    lcs记录公共子串
//    return    公共子串长度
int LCS(const char *str1  , int len1 , const char *str2 , int len2 , char *&lcs)
{
if(NULL == str1 || NULL == str2)
{
return -1;    //空参数
}
//    压缩后的最长子串记录向量
int *c = new int[len2+1];
for(int i = 0 ; i < len2 ; ++i)
{
c[i] = 0;
}
int max_len = 0;    //匹配的长度
int pos = 0;        //在str2上的匹配最末位置
for(int i = 0 ; i < len1 ; ++i)
{
for(int j = len2 ; j > 0 ; --j)    //更新时从后往前遍历
{
if(str1[i] == str2[j-1])
{
c[j] = c[j-1] + 1;
if(c[j] > max_len)
{
max_len = c[j];
pos = j-1;
}
}
else
{
c[j] = 0;
}
}
}

if(0 == max_len)
{
delete [] c;
return 0;
}

//    得到公共子串
lcs = new char[max_len];
for(int i = 0 ; i < max_len ; ++i)
{
lcs[i] = str2[pos-max_len+1+i];
}
cout<<"pos = "<<pos<<endl;
delete [] c;
return max_len;

}

//    test
int main()
{
const char *str1 = "abacaba";
const char *str2 = "caba";
int len1 = strlen(str1);
int len2 = strlen(str2);

char *lcs;

int len = LCS(str1 , len1 , str2 , len2 , lcs);
cout<<"max length = "<<len<<endl;
for(int i = 0 ; i < len ; ++i)
{
cout<<lcs[i]<<" ";
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法