#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; }