以下内容转载自http://blog.csdn.net/hackbuteer1/article/details/6686931(题目)
和July(解法)
求两个串中的第一个最长子串(神州数码以前试题)。如"abractyeyt","dgdsaeactyey"的最大子串为"actyet"。
http://blog.csdn.net/miao6664659/article/details/8206471
http://blog.csdn.net/miao6664659/article/details/8205447
解法如下:
char str1[]="abractyeyt";
char str2[]="dgdsaeactyey";
#define N sizeof(str1)-2
#define W sizeof(str2)-2
int path[N][W];
int sum=0;
int t=0;
int begin;
int LCS_2(char *str1,char *str2,int len1,int len2)
{
if(len1<=0||len2<=0)
return 0;
else
{
for(int i=0;i<len1;i++)
{
for(int j=0;j<len2;j++)
{
if(str1[i]==str2[j])
{
path[i+1][j+1]=path[i][j]+1;
}
else
{
path[i+1][j+1]=0;
}
if(path[i+1][j+1]>sum)
{
begin=i-sum;
sum=path[i+1][j+1];
}
}
}
}
return sum;
}
int LCS_1(char *str1,char *str2,int len1,int len2)
{
if(len1<=0||len2<=0)
return 0;
for(int i=1;i<=len1;i++)
{
for(int j=1;j<=len2;j++)
{
// if(*(str1+i-1)==*(str2+j-1))
if(str1[i-1]==str2[j-1])
{
path[i][j]=path[i-1][j-1]+1;
}
else
{
path[i][j]=0;
}
if(path[i][j]>=sum)
sum=path[i][j];
}
}
return sum;
}
int LCS(char *str1,char *str2,int len1,int len2)
{
if(len1<=0||len2<=0)
return 0;
for(int i=0;i<len1;i++)
{
for(int j=0;j<len2;j++)
{
if(*(str1+len1-1)==*(str2+len2-1))
{
path[len1-1][len2-1]=1;
return LCS(str1,str2,len1-1,len2-1)+1;
}
else
{
int a=LCS(str1,str2,len1,len2-1);
int b=LCS(str1,str2,len1-1,len2);
if(a>b)
{
path[len1-1][len2-1]=2;
}
else
path[len1-1][len2-1]=-1;
return a>b?a:b;
}
}
}
}
void Print_1(int m)
{
int i=0;
while(i<m)
{
cout<<*(str1+begin+i++);
}
}
void Print()
{
std::stack<char> st;
//for(int i=0;i<=N;i++)
//{
// for(int j=0;j<=W;j++)
// cout<<path[i][j]<<" ";
// cout<<endl;
//}
//cout<<endl;
int i=N,j=W;
while(i>=0&&j>=0)
{
if(path[i][j]==-1)
{
i=i-1;
}
else if(path[i][j]==1)
{
st.push(str2[j]);
i--;
j--;
}
else
j=j-1;
}
while(!st.empty())
{
cout<<st.top();
st.pop();
}
cout<<endl;
}
int main()
{
int m=LCS_2(str1,str2,strlen(str1),strlen(str2));
cout<<m<<endl;
Print_1(m);
cout<<endl;
cout<<LCS(str1,str2,strlen(str1),strlen(str2))<<endl;
Print();
return 0;
}