zoukankan      html  css  js  c++  java
  • 最长公共子序列与最长公共字串

    显然最长公共子序列不一定需要连续的,只要字符的顺序严格递增即可。最长公共字串需要字符连续

    子序列代码:

    package test;
    
    import java.util.*;
    /*
     * 本题是求最长公共子序列,子序列未必连续,只需要严格递增即可
     * 如  abcdeeeeeeeee和atttbggcd 最长公共子序列为abcd 长度为4
     * 
     * */
    public class Main4{
        public static void main(String... args){
            try(Scanner in = new Scanner(System.in)){
                while(in.hasNext()){
                
                    String s1 = in.nextLine();
                    String s2 = in.nextLine();
                    String min1 = s1.length() < s2.length()? s1 : s2;
                    String max1 = s1.equals(min1) ? s2 : s1;
                     //dp[i][j]表示i串和j串的最长公共字串
                    char[] min = min1.toCharArray();
                    char[] max = max1.toCharArray();
                    int[][] dp = new int[max.length+1][max.length+1]; 
                    for(int i = 1; i < min.length + 1;i++) {
                        for(int j = 1; j < max.length + 1;j++) {
                            if(min[i-1] == max[j-1]) {
                                dp[i][j] = dp[i-1][j-1] + 1;
                            }else {
                                dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
                            }    
                        }
                    }
                    
                    for(int i = 0; i < min.length + 1; i++) {
                        for(int j = 0; j < max.length + 1;j++) {
                            if(j == max.length)
                                System.out.println(dp[i][j]);
                            else System.out.print(dp[i][j] + "  ");
                        }
                    }
                    System.out.println("++++++++++++++++++++");
                    int flag = 0;
                    for(int i = 0; i < min.length + 1;i++) {
                        for(int j = 0; j < max.length + 1; j++) {
                            if(dp[i][j] == flag + 1) {
                                System.out.print(max[j-1]);
                                flag = dp[i][j];
                            }
                        }
                    }
                }
            }
        }
    }

    最长公共字串代码

    package test;
    
    import java.util.*;
    public class Main2{
        public static void main(String... args){
            try(Scanner in = new Scanner(System.in)){
                while(in.hasNext()){
                
                    String s1 = in.nextLine();
                    String s2 = in.nextLine();
                    String min1 = s1.length() < s2.length()? s1 : s2;
                    String max1 = s1.equals(min1) ? s2 : s1;
                     //dp[i][j]表示i串和j串的最长公共字串
                    char[] min = min1.toCharArray();
                    char[] max = max1.toCharArray();
                    int[][] dp = new int[max.length+1][max.length+1]; 
                    for(int i = 1; i < min.length + 1;i++) {
                        for(int j = 1; j < max.length + 1;j++) {
                            if(min[i-1] == max[j-1]) {
                                dp[i][j] = dp[i-1][j-1] + 1;
                            }
                        }
                    }
                    
                    for(int i = 0; i < min.length + 1; i++) {
                        for(int j = 0; j < max.length + 1;j++) {
                            if(j == max.length)
                                System.out.println(dp[i][j]);
                            else System.out.print(dp[i][j] + "  ");
                        }
                    }
                    System.out.println("++++++++++++++++++++");
                    int flag = 0;
                    int MAX = 0;
                    int end = 0;
                    
                    for(int i = 1; i < min.length + 1;i++) {
                        for(int j = 1; j < max.length + 1; j++) {
                            if(dp[i][j] > MAX) {
                                MAX = dp[i][j];
                                end = j;
                            }
                        }
                    }
                    System.out.println("MAX为:"+ MAX);
                    System.out.println("end为:"+ end);
                    for(int i = end - MAX ; i < end; i++) {
                        if(i == end - 1) System.out.println(max[i]);
                        else System.out.print(max[i]);
                    }
                }
            }
        }
    }

    仔细比对两处代码可知,公共子序列需要将每一次循环中记录子序列的结果,dp的值一直更新(虽然值有可能不变)。而公共字串只有当字符连续的时候,dp值才会发生更新。

    公共子序列在输出结果时,我们可以先把状态矩阵打印出来,观察矩阵可知,当每组数据第一次发生变化,就是子序列的值。比如

    当然,也可以纵向理解,则打印出min的第一次变化处的值即可。

  • 相关阅读:
    metal的gpu query
    体积雾 global fog unity 及改进
    hdr rt format对颜色的影响
    unity deferred lighting
    unity linear space时 photoshop blend的正确设置
    unity linear work flow
    一些数据 bandwidth之类
    deferred rendering with msaa
    unity 显示mipmaplevel
    【转】在C#中使用SendMessage
  • 原文地址:https://www.cnblogs.com/theWinter/p/11260340.html
Copyright © 2011-2022 走看看