说一下前天腾讯实习的笔试题--字符串回文问题(动态规划)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了说一下前天腾讯实习的笔试题--字符串回文问题(动态规划)相关的知识,希望对你有一定的参考价值。

题目描述
最长回文子序列:
一个给定的字符串,求其最长回文子序列的长度;
一个回文子序列定义为原字符串的一个子序列去掉某些字符后生成的字符串为一个回文字符串;
例如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 }

 

 

以上是关于说一下前天腾讯实习的笔试题--字符串回文问题(动态规划)的主要内容,如果未能解决你的问题,请参考以下文章

腾讯2017暑期实习生编程题 第一题 构造回文

腾讯2017暑期实习生编程题

腾讯2017暑期实习生编程题

笔试题81. 腾讯2017暑期实习生笔试题

腾讯2017暑期实习生笔试题解题答案汇总

腾讯2017暑期实习生编程题