zoukankan      html  css  js  c++  java
  • 动态规划算法实现部分——求公共最长子序列以及构造回文需要删除的最小字符个数

    上学期的期末考为了应付考试,只是把每种算法都理解了一遍,但是并没有具体的代码实现。现在开始抽空慢慢实现这些算法。

    代码实现:

    import java.util.Scanner;
    
    public class Main2
    {
        public static void main(String[] args){
            //从键盘输入第一个字符串
            Scanner in=new Scanner(System.in);
            String string1=in.nextLine();
            //从键盘输入第二个字符串
            String string2=in.nextLine();
            in.close(); //关闭输入
            
            char[] chars1=string1.toCharArray();
            char[] chars2=string2.toCharArray();
            int length1=string1.length();
            int length2=string2.length();
            
            /*这里要加1,因为要构造的那个二维数组是行和列都是从0比到6的
              会比原字符串的长度多1
            */
            int dp[][]=new int[length1+1][length2+1];
            /*后面为了对齐方向箭头打印位置初始从1开始打印,所以这里长度加2,避免数组溢出*/
            char b[][]=new char[length1+2][length2+1];
                
            /*构造第一排和第一列的所有的0*/
            for(int i=0; i<=length1;i++){
                dp[i][0]=0;
            }
            for(int j=1;j<=length2;j++){
                dp[0][j]=0;
            }
            
            //自底向上计算
            for(int i=1;i<=length1;i++){
                for(int j=1;j<=length2;j++){
                    if(chars1[i-1]==chars2[j-1]){
                        dp[i][j]=dp[i-1][j-1]+1;
                        b[i][j]='↖';
                    }else if(dp[i][j-1]>dp[i-1][j]){
                        dp[i][j]=dp[i][j-1];
                        b[i][j]='←';
                    }else{
                        dp[i][j]=dp[i-1][j];
                        b[i][j]='↑';
                    }
                }
            }
            
            /*输出*/
            for(int i=0;i<=length1;i++){
                for(int j=0;j<=length2;j++){
                    System.out.print(dp[i][j]+"  ");
                }
                System.out.println();
                for(int j=0;j<=length2;j++){
                    System.out.print(b[i+1][j]+" ");//为了对齐方向箭头,从第二行开始逐行打印
                }
                System.out.println();
            }
        }
    }

     结果:

    这里有个算法的衍生,就是求构造回文需要删除的最小字符个数。其实只需要将一个字符串和它的逆序字符串求公共最长子串就可以了。

    import java.util.Scanner;
    
    public class Main
    {
        public static void main(String[] args){
            Scanner in=new Scanner(System.in);
            while(in.hasNext()){ //循环输入
                String string=in.nextLine();
                char[] chars=string.toCharArray();
                int length=string.length();
                int dp[][]=new int[length+1][length+1];
                
                /*构造第一排和第一列的所有的0*/
                for(int i=0; i<length+1;i++){
                    dp[i][0]=0;
                    dp[0][i]=0;
                }
                //自底向上计算
                for(int i=1;i<=length;i++){
                    for(int j=1;j<=length;j++){
                        if(chars[i-1]==chars[length-j]){
                            dp[i][j]=dp[i-1][j-1]+1;
                        }else if(dp[i][j-1]>dp[i-1][j]){
                            dp[i][j]=dp[i][j-1];
                        }else{
                            dp[i][j]=dp[i-1][j];
                        }
                    }
                }
                //输出构造回文需要删除的最少字符的个数
                System.out.println(length - dp[length][length]);
            }
        }
    }
  • 相关阅读:
    【Java】快速排序、归并排序、堆排序、基数排序实现总结
    【Java】二分查找、插值查找、斐波那契查找的实现,及分析
    【Java】Java实现常见的七种排序
    【C】常见的排序
    栈,迷宫问题
    海量数据处理问题
    【C】 布隆过滤器BloomFilter
    哈希变形---位图
    C实现Hash表,链式结构
    C实现Hash表,开放定址法
  • 原文地址:https://www.cnblogs.com/f91og/p/6477207.html
Copyright © 2011-2022 走看看