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的第一次变化处的值即可。

  • 相关阅读:
    20155226《网络攻防》 实验4 恶意代码分析
    20155226《网络攻防》 Exp3 免杀原理与实践
    20155226 Exp2 后门原理与实践
    20155226 《网络攻防》 Exp1 PC平台逆向破解(5)M
    2017-2018-1 20155226 《信息安全系统设计基础》课程总结
    《基于Arm实验箱的国密算法应用》课程设计 结题报告
    2015520吴思其 基于《Arm试验箱的国密算法应用》课程设计个人报告
    20155220 Exp9 Web安全基础实践
    20155220 《网络对抗》Exp 8 Web基础
    20155220 《网络对抗》实验七 网络欺诈防范
  • 原文地址:https://www.cnblogs.com/theWinter/p/11260340.html
Copyright © 2011-2022 走看看