#include<iostream>
#include <vector>
using namespace std;
//enum decreaseDire {kInit = 0,kLeft = 1,kUp = 2,kLeftUp = 4};
enum decreaseDire {kInit = 0,kLeft = 1,kUp = 2,kLeftUp = 4};
//打印任意一个公共子序列
void LCS_Print(int **LCS_direction,const char* pStr1,const char* pStr2,size_t row,size_t col)
{
if(!pStr1 || !pStr2)
return ;
size_t length1 = strlen(pStr1);
size_t length2 = strlen(pStr2);
if(length1 == 0 || length2 == 0)
return ;
if(row>=length1 || col>=length2 || row<0 || col<0)
return ;
if(LCS_direction[row][col] == kLeftUp){
LCS_Print(LCS_direction,pStr1,pStr2,row-1,col-1); printf("%c",pStr1[row]);
}else if(LCS_direction[row][col] == kLeft){
LCS_Print(LCS_direction,pStr1,pStr2,row,col-1);
}else if(LCS_direction[row][col] == kUp){
LCS_Print(LCS_direction,pStr1,pStr2,row-1,col);
}
return ;
}
//打印任意所有公共子序列
void LCS_Print_AllSeq(int **LCS_direction,const char* pStr1,const char* pStr2,size_t row,size_t col,char *result,int start)
{
if(!pStr1 || !pStr2)
return ;
size_t length1 = strlen(pStr1);
size_t length2 = strlen(pStr2);
if(length1 == 0 || length2 == 0)
return ;
if(row>=length1 || col>=length2 || row<0 || col<0){
printf("%s\n",result+start+1);
return ;
}
switch(LCS_direction[row][col]){
case kLeft:
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row,col-1,result,start);
break;
case kUp:
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col,result,start);
break;
case kLeftUp:
result[start] = pStr1[row];
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col-1,result,start-1); //printf("%c",pStr1[row]);
break;
case kLeft+kUp:
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row,col-1,result,start);
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col,result,start);
break;
case kLeft+kLeftUp:
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row,col-1,result,start);
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col-1,result,start-1); //printf("%c",pStr1[row]);
break;
case kUp+kLeftUp:
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col,result,start);
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col-1,result,start-1); //printf("%c",pStr1[row]);
break;
case kLeft+kUp+kLeftUp:
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row,col-1,result,start);
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col,result,start);
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,row-1,col-1,result,start-1); //printf("%c",pStr1[row]);
break;
}
// if(LCS_direction[row][col] == kLeftUp){
// LCS_Print(LCS_direction,pStr1,pStr2,row-1,col-1); printf("%c",pStr1[row]);
// }
// if(LCS_direction[row][col] == kLeft){
// LCS_Print(LCS_direction,pStr1,pStr2,row,col-1);
// }
// if(LCS_direction[row][col] == kUp){
// LCS_Print(LCS_direction,pStr1,pStr2,row-1,col);
// }
}
//subsequence
int LCS(const char* pStr1,const char* pStr2)
{
if(!pStr1 || !pStr2)
return 0;
size_t length1 = strlen(pStr1);
size_t length2 = strlen(pStr2);
if(length1 == 0 || length2 == 0)
return 0;
int **LCS_length,**LCS_direction;
size_t i,j;
LCS_length = new int*[length1]; LCS_direction = new int*[length1];
for(i=0;i<length1;i++){
LCS_length[i] = new int[length2]; LCS_direction[i] = new int[length2];
}
for(i=0;i<length1;i++){
for(j=0;j<length2;j++){
LCS_length[i][j] = 0; LCS_direction[i][j] = kInit;
}
}
for(i=0;i<length1;i++){
for(j=0;j<length2;j++){
if(i==0 || j==0){
if(pStr1[i] == pStr2[j]){
LCS_length[i][j] = 1; LCS_direction[i][j] = kLeftUp;
}
}else if(pStr1[i] == pStr2[j]){
LCS_length[i][j] = LCS_length[i-1][j-1]+1; LCS_direction[i][j] = kLeftUp;
}else if(LCS_length[i-1][j] >= LCS_length[i][j-1]){
LCS_length[i][j] = LCS_length[i-1][j]; LCS_direction[i][j] = kUp;
}else{
LCS_length[i][j] = LCS_length[i][j-1]; LCS_direction[i][j] = kLeft;
}
//printf("%2d ",LCS_length[i][j]);
printf("%2d ",LCS_direction[i][j]);
}
printf("\n");
}
LCS_Print(LCS_direction,pStr1,pStr2,length1-1,length2-1);
return LCS_length[length1-1][length2-1];
}
//AllSeq
int LCS_AllSeq(const char* pStr1,const char* pStr2)
{
if(!pStr1 || !pStr2)
return 0;
size_t length1 = strlen(pStr1);
size_t length2 = strlen(pStr2);
if(length1 == 0 || length2 == 0)
return 0;
int **LCS_length,**LCS_direction;
size_t i,j;
LCS_length = new int*[length1]; LCS_direction = new int*[length1];
for(i=0;i<length1;i++){
LCS_length[i] = new int[length2]; LCS_direction[i] = new int[length2];
}
for(i=0;i<length1;i++){
for(j=0;j<length2;j++){
LCS_length[i][j] = 0; LCS_direction[i][j] = kInit;
}
}
for(i=0;i<length1;i++){
for(j=0;j<length2;j++){
if(i==0 && j==0){
if(pStr1[i] == pStr2[j]){
LCS_length[i][j] = 1; LCS_direction[i][j] += kLeftUp;
}
}else if(i==0 || j==0){
if(pStr1[i] == pStr2[j]){
LCS_length[i][j] = 1; LCS_direction[i][j] += kLeftUp;
}
if(i==0){
if(LCS_length[i][j-1] == 1){
LCS_length[i][j] = 1;
LCS_direction[i][j] += kLeft;
}
}else{
if(LCS_length[i-1][j] == 1){
LCS_length[i][j] = 1;
LCS_direction[i][j] += kUp;
}
}
}
if(i!=0 && j!=0){
if(pStr1[i] == pStr2[j]){
LCS_length[i][j] = LCS_length[i-1][j-1]+1; LCS_direction[i][j] += kLeftUp;
if(LCS_length[i-1][j] == LCS_length[i][j]){
LCS_direction[i][j] += kUp;
}
if(LCS_length[i][j-1] == LCS_length[i][j]){
LCS_direction[i][j] += kLeft;
}
}else{
if(LCS_length[i-1][j] == LCS_length[i][j-1]){
LCS_length[i][j] = LCS_length[i-1][j];
LCS_direction[i][j] += kUp;
LCS_direction[i][j] += kLeft;
}else if(LCS_length[i-1][j] > LCS_length[i][j-1]){
LCS_length[i][j] = LCS_length[i-1][j];
LCS_direction[i][j] += kUp;
}else{
LCS_length[i][j] = LCS_length[i][j-1];
LCS_direction[i][j] += kLeft;
}
}
}
printf("%2d ",LCS_direction[i][j]);
//printf("%2d ",LCS_length[i][j]);
}
printf("\n");
}
char *result = new char[length1+1];
result[length1] = '\0';
LCS_Print_AllSeq(LCS_direction,pStr1,pStr2,length1-1,length2-1,result,length1-1);
return LCS_length[length1-1][length2-1];
}
//substring
int LCString(const char* pStr1,const char* pStr2)
{
if(!pStr1 || !pStr2)
return 0;
size_t length1 = strlen(pStr1);
size_t length2 = strlen(pStr2);
if(length1 == 0 || length2 == 0)
return 0;
int **LCS_length,**LCS_direction;
size_t i,j;
LCS_length = new int*[length1]; LCS_direction = new int*[length1];
for(i=0;i<length1;i++){
LCS_length[i] = new int[length2]; LCS_direction[i] = new int[length2];
}
for(i=0;i<length1;i++){
for(j=0;j<length2;j++){
LCS_length[i][j] = 0; LCS_direction[i][j] = kInit;
}
}
int maxLen = 0;int maxI = 0,maxJ = 0;
for(i=0;i<length1;i++){
for(j=0;j<length2;j++){
if(i==0 || j==0){
if(pStr1[i] == pStr2[j]){
LCS_length[i][j] = 1; LCS_direction[i][j] = kLeftUp;
}
}else if(pStr1[i] == pStr2[j]){
if(LCS_direction[i-1][j-1] = kLeftUp){
LCS_length[i][j] = LCS_length[i-1][j-1]+1; LCS_direction[i][j] = kLeftUp;
}
else{
LCS_length[i][j] = 1; LCS_direction[i][j] = kLeftUp;
}
}
if(LCS_length[i][j] > maxLen){
maxLen = LCS_length[i][j];
maxI = i; maxJ = j;
}
}
}
//LCS_Print(LCS_direction,pStr1,pStr2,length1-1,length2-1);
//return LCS_length[length1-1][length2-1];
LCS_Print(LCS_direction,pStr1,pStr2,maxI,maxJ);
return maxLen;
}
int main()
{
char Str1[] = "BDCABA",Str2[] = "ABCBDAB";
//char Str1[] = "dhajhfakdfjkahfahakjhfjahyfhgqioqurjdnachhzjjckaghda",Str2[] = "qyuiaudhajndjahdfjajdalkfdyi8qyahjkdhajhdfahfjhasfka";
//char Str1[] = "dhajhfakdfjkahfahakjhfa",Str2[] = "qyuiaudhajndjahdhasfka";
int Len;
//Len = LCS(Str1,Str2); //子串
//Len = LCS_AllSeq(Str1,Str2); //所有子串
Len = LCString(Str1,Str2); //子序列
cout<<endl<<Len<<endl;
return 0;
}
子序列、子串问题
最新推荐文章于 2024-07-08 08:41:57 发布