题目描述
最长回文子序列:
一个给定的字符串,求其最长回文子序列的长度;
一个回文子序列定义为原字符串的一个子序列去掉某些字符后生成的字符串为一个回文字符串;
例如cabbeaf:回文子序列有:c,a,aa,bb,,aba,abba,e,f,最长的就是abba,所以输出长度为4。
解题思路:
该问题为一个典型的动态规划问题,原串和反转串的最长公共子序列的长度即为该问题的解。
我实现的代码如下(我还多写了一些代码,用递归的方法来求解出了最长公共子序列的字符串):
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #define MAX_LEN 1000 + 10 6 7 int result[MAX_LEN][MAX_LEN]; 8 int status[MAX_LEN][MAX_LEN]; //辅助数组,用来记录每个值是在哪种情况生成的,为后续生成最长公共子序列做准备 9 10 /* 11 *最长公共子序列动态规划方程 12 * 13 *m[i][j]代表序列Xi和序列Yi的最长公共自学列的长度 14 * 15 *m[i][j] ={ 16 * 0; i =0 || j =0; 17 * m[i-1][j-1] + 1; str1[i] = st2[j]; 18 * max(m[i][j-1], m[i-1][j]) str1[i] != str2[j] 19 * } 20 */ 21 22 /*两个字符串的最长公共子序列*/ 23 int lcs(char str1[],int str1_len,char str2[],int str2_len) 24 { 25 int i,j; 26 for(i = 1; i < str1_len; i++) 27 { 28 for(j = 1; j < str2_len; j++) 29 { 30 if(str1[i] == str2[j]) 31 { 32 result[i][j] = result[i - 1][j - 1] + 1; 33 status[i][j] = 1; //记录为情况1 34 } 35 else if(result[i-1][j] >= result[i][j-1]) 36 { 37 result[i][j] = result[i - 1][j]; 38 status[i][j] = 2; //记录为情况2 39 } 40 else 41 { 42 result[i][j] = result[i][j - 1]; 43 status[i][j] = 3; //记录为情况3 44 } 45 } 46 } 47 48 return result[str1_len - 1][str2_len - 1]; 49 } 50 51 52 /*反转字符串*/ 53 void reverse_str(char str_old[],int str_len,char str_new[]) 54 { 55 int i,j; 56 57 for(i = 0, j = str_len - 1; i < str_len; i++) 58 { 59 str_new[i] = str_old[j]; 60 j--; 61 } 62 } 63 64 /*构造最长公共子序列*/ 65 void lcs_construct(int i,int j,char *str_old) 66 { 67 if(i == 0 || j == 0) 68 { 69 return; 70 } 71 72 if(status[i][j] == 1) 73 { 74 lcs_construct(i - 1,j - 1,str_old); 75 printf("%c",str_old[i]); 76 } 77 else if(status[i][j] == 2) 78 { 79 lcs_construct(i - 1,j,str_old); 80 } 81 else 82 { 83 lcs_construct(i,j - 1,str_old); 84 } 85 } 86 87 int main() 88 { 89 char str_old[MAX_LEN],str_new[MAX_LEN]; 90 int len; 91 while(scanf("%s",str_old) != EOF) 92 { 93 reverse_str(str_old,strlen(str_old),str_new); 94 95 len = lcs(str_old,strlen(str_old),str_new,strlen(str_new)); 96 97 printf("最长公共子序列长度为:%d\n",len); 98 printf("最长公共子序列为:"); 99 lcs_construct(strlen(str_old) - 1,strlen(str_new) - 1,str_old); 100 printf("\n"); 101 } 102 }
时间: 2024-10-12 10:15:14