动态规划,最长回文子序列(java实现),输入character,算法应该返回carac

来源:互联网 发布:电脑锣编程软件有什么 编辑:程序博客网 时间:2024/06/03 13:18
  1. 因为考试要考动态规划,所以研究了下算法,参考了网上许多资料,但是自己总结一次,印象会更加深刻。
  2. 源题目是输入character,这里换一个短点的,好分析一点,以bcdca为例。
  3. 以db[i][j]代表从字符索引i到字符索引j的最长回文子序列。当然db[0][4]就是指的bcdca的最长回文子序列。其实这个问题和最长公共子序列问题非常像。
  4. 接下来,我们考虑如何求db[0][4]的最长回文子序列。这里写图片描述
    我们很容易得到下面的递归程序
private static int getResult(char[] con, int i, int j) {        // TODO Auto-generated method stub        if (i==j) {            return 1;        }        if (i>j) {            return 0;        }        if (con[i]==con[j]) {            return getResult(con, i+1, j-1)+2;        }else {            return Math.max(getResult(con, i+1, j),getResult(con, i, j-1));        }    }

5.于是就通过递归算出了dp[0][4]=3,于是我们很容易得出下面这张表格。在这张表格中我们能查到dp[i][j]的任意值。这个代码实现部分就是两次循环。我会在后面给出来。
这里写图片描述
6.这里我们得到了最长子回文的长度,接下来就是如何把这个字符串求出来的问题。我们简单了分析一下思路,以dp[0][4]以例,这个其它就是2+1,这里面的2就代表着有首尾相等的情况,我们把这个首尾相等时的i和j求出来。不就得到了回文的字母吗?也就是说通过还原dp的求解过程。得到回文的字母。
7.代码如下,将输入换成character.

public class huiwen {    public static void main(String[] args) {        // TODO Auto-generated method stub       String con="character";       int[][] db=new int[9][9];        //生成二维数组表       for(int i=0;i<con.length();i++)       {           for(int j=i;j<con.length();j++)           {               db[i][j]=getResult(con.toCharArray(), i, j);              // System.out.println("db"+"["+i+"]"+"["+j+"]"+db[i][j]);           }       }       char[] res=new char[db[0][con.length()-1]];  //得到回文长度       int m=0;        //m代表结果字符数组索引开始       int n=res.length-1;  //n代表结果字符数组索引最后一位        char[] res1=con.toCharArray();         int i=0;       int j=con.length()-1;       int index=res.length-1;   //得到循环次数       //还原dp的,从开头和结尾同时开始       while(index>=0)       {           if (i<con.length()&&db[i][j]==db[i+1][j]) {            i++;        }else if (j>=0&&db[i][j]==db[i][j-1]) {            j--;        }else {            //这种情况就代表dp[i][j]=dp[i+1][j-1]+2这种情况,这里的首和尾是相同的。取出首            //和尾的字符填充到结果字符数组中,然后i++,j--继续从两边向中间搜索。            res[m]=res1[i];            res[n]=res1[j];            i++;            j--;            m++;            n--;            index=index-2; //一次填充两个字符        }       }       //将结果字符数组生成字符串       System.out.println(String.valueOf(res));    }    private static int getResult(char[] con, int i, int j) {        // TODO Auto-generated method stub        if (i==j) {            return 1;        }        if (i>j) {            return 0;        }        if (con[i]==con[j]) {            return getResult(con, i+1, j-1)+2;        }else {            return Math.max(getResult(con, i+1, j),getResult(con, i, j-1));        }    }}
0 0
原创粉丝点击