一个粗糙的打印两序列所有最大公共子序列的方法
以下是典型动态算法打印两序列最大公共子序列的方法,该方法只能打印一个最大公共子序列:
1 #include <iostream> 2 using std::cout; 3 using std::endl; 4 5 const int NUM1=30,NUM2=30; 6 char result[NUM1+1]; 7 int count=0; 8 int lcsLength(char x[], char y[], int b[][NUM2+1],int m,int n) 9 { 10 int c[NUM1+1][NUM2+1]; 11 for (int i = 0; i<=m; i++) 12 c[i][0]=0; 13 for (int i = 0; i<=n; i++ ) 14 c[0][i]=0; 15 for (int i = 1; i <= m; i++) 16 { 17 for (int j = 1; j <= n; j++) 18 { 19 if (x[i - 1]==y[j - 1]) 20 { 21 c[i][j]=c[i-1][j-1]+1; 22 b[i][j]=1; 23 } 24 else 25 if (c[i-1][j]>c[i][j-1]) 26 { 27 c[i][j]=c[i-1][j]; 28 b[i][j]=2; 29 } 30 else 31 { 32 c[i][j]=c[i][j-1]; 33 b[i][j]=3; 34 } 35 } 36 } 37 return c[m][n]; 38 } 39 40 void lcs(int i,int j, char x[], int b[][NUM2+1] ) 41 { 42 if (i ==0 || j==0) 43 return; 44 45 if(b[i][j]== 1) 46 { 47 lcs(i-1, j-1, x, b); 48 cout<<x[i-1]; 49 } 50 else 51 if(b[i][j] == 2) 52 lcs(i-1, j, x, b); 53 else 54 lcs(i, j-1, x, b); 55 } 56 57 int _tmain(int argc, _TCHAR* argv[]) 58 { 59 char * x = "3123"; 60 char * y ="132"; 61 int xlen = strlen(x); 62 int ylen = strlen(y); 63 int b[NUM1 + 1][NUM2 + 1]; 64 int len = lcsLength( x, y, b, xlen,ylen ); 65 cout<<len<<endl; 66 lcs( xlen,ylen, x, b); 67 68 getchar(); 69 return 0; 70 }
只考虑最终的最优解,而不输出所有最优解或许是动态算法的很大的缺点。就这个问题,下面是一个粗糙的打印两序列所有最大公共子序列的方法:
1 #include <iostream> 2 using std::cout; 3 using std::endl; 4 5 const int NUM1=30,NUM2=30; 6 char result[NUM1+1]; 7 int count=0; 8 int lcsLength(char x[], char y[], int b[][NUM2+1],int m,int n) 9 { 10 int c[NUM1+1][NUM2+1]; 11 for (int i = 0; i<=m; i++) 12 c[i][0]=0; 13 for (int i = 0; i<=n; i++ ) 14 c[0][i]=0; 15 for (int i = 1; i <= m; i++) 16 { 17 for (int j = 1; j <= n; j++) 18 { 19 if (x[i - 1]==y[j - 1]) 20 { 21 c[i][j]=c[i-1][j-1]+1; 22 b[i][j]=1; 23 } 24 else 25 if (c[i-1][j]>c[i][j-1]) 26 { 27 c[i][j]=c[i-1][j]; 28 b[i][j]=2; 29 } 30 else 31 if(c[i-1][j]<c[i][j-1]) 32 { 33 c[i][j]=c[i][j-1]; 34 b[i][j]=3; 35 } 36 else 37 { 38 c[i][j]=c[i][j-1]; //或者c[i][j]=c[i-1][j]; 39 b[i][j]=4; 40 } 41 } 42 } 43 return c[m][n]; 44 } 45 46 void lcs(int i,int j, char x[], int b[][NUM2+1],int idx,int len) 47 { 48 if (i ==0 || j==0) 49 { 50 for(int s=0;s<len;s++) 51 cout<<result[s]; 52 cout<<endl; 53 count++; 54 return; 55 } 56 int t=b[i][j]; 57 if(b[i][j]== 1) 58 { 59 idx--; 60 result[idx]=x[i- 1]; 61 lcs(i-1, j-1, x, b,idx,len); 62 } 63 else 64 if(b[i][j] == 2) 65 lcs(i-1, j, x, b,idx,len); 66 else 67 if(b[i][j]==3) 68 lcs(i, j-1, x, b,idx,len); 69 else 70 { 71 lcs(i,j-1,x,b,idx,len); 72 lcs(i-1,j,x,b,idx,len); 73 } 74 } 75 76 int _tmain(int argc, _TCHAR* argv[]) 77 { 78 char * x = "3123"; 79 char * y ="132"; 80 int xlen = strlen(x); 81 int ylen = strlen(y); 82 int b[NUM1 + 1][NUM2 + 1]; 83 int len = lcsLength( x, y, b, xlen,ylen ); 84 cout<<len<<endl; 85 lcs( xlen,ylen, x, b,len,len ); 86 cout<<"共有:"<<count<<"种"; 87 getchar(); 88 return 0; 89 }
**************************************************************
我喜欢程序员,他们单纯、固执、容易体会到成就感;面对困难,能够不休不眠;面对压力,能够迎接挑战。他们也会感到困惑与傍徨,但每个程序员的心中都有一个比尔盖茨或是乔布斯的梦想,用智慧把属于自己的事业开创。其实我是一个程序员[=.=]
我喜欢程序员,他们单纯、固执、容易体会到成就感;面对困难,能够不休不眠;面对压力,能够迎接挑战。他们也会感到困惑与傍徨,但每个程序员的心中都有一个比尔盖茨或是乔布斯的梦想,用智慧把属于自己的事业开创。其实我是一个程序员[=.=]