美文网首页程序员半栈工程师
HDU 1503 Advanced Fruits 最长公共子串应

HDU 1503 Advanced Fruits 最长公共子串应

作者: TinyDolphin | 来源:发表于2017-12-12 12:13 被阅读0次

LCS 算法应用,求出最长公共子串,而非长度。

LCS 算法轨迹,来自算法导论
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Scanner;

/**
 * 题意:把两个单词拼接成一个新单词,使得新单词的子序列中包含两个单词,并且要使这个新单词最短
 *
 * 思路:先利用 LCS 算法求出最长公共子串,然后拼接输出即可。
 *
 */
public class Main {

    private static int[][] maxLen = new int[1000][1000];

    private static String work(String str1, String str2) {
        StringBuilder result = new StringBuilder();
        char[] ch1 = str1.toCharArray();
        char[] ch2 = str2.toCharArray();
        int length1 = ch1.length;
        int length2 = ch2.length;
        // 正常 LCS 算法
        for (int indexI = 1; indexI <= length1; indexI++) {
            for (int indexJ = 1; indexJ <= length2; indexJ++) {
                if (ch1[indexI - 1] == ch2[indexJ - 1]) {
                    maxLen[indexI][indexJ] = maxLen[indexI - 1][indexJ - 1] + 1;
                } else {
                    maxLen[indexI][indexJ] = Math.max(maxLen[indexI - 1][indexJ], maxLen[indexI][indexJ - 1]);
                }
            }
        }
        // 规则处理:当没有最长公共子串时,输出两个字符串全部字符。
        if (maxLen[length1][length2] == 0) {
            result.append(str1).append(str2);
        } else {
            int indexI = length1;
            int indexJ = length2;
            // 反向进行比较
            while (indexI > 0 && indexJ > 0) {
                // 将最长公共子串字符拼接到 result
                if (maxLen[indexI][indexJ] == maxLen[indexI - 1][indexJ - 1] + 1 && ch1[indexI - 1] == ch2[indexJ - 1]) {
                    result.append(ch1[indexI - 1]);
                    indexI--;
                    indexJ--;
                } else {
                    // 将两个字符串中字符(不属于最长公共子串的字符)拼接到 result
                    if (maxLen[indexI][indexJ] == maxLen[indexI - 1][indexJ]) {
                        result.append(ch1[--indexI]);
                    } else {
                        result.append(ch2[--indexJ]);
                    }
                }
            }
            // 将剩余的字符全部存储到 result
            while (indexI > 0) {
                result.append(ch1[--indexI]);
            }
            while (indexJ > 0) {
                result.append(ch2[--indexJ]);
            }
        }
        return result.reverse().toString();
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        String str1;
        String str2;
        while (in.hasNext()) {
            str1 = in.next();
            str2 = in.next();
            out.println(work(str1, str2));
        }
        out.flush();
    }
}

相关文章

  • HDU 1503 Advanced Fruits 最长公共子串应

    LCS 算法应用,求出最长公共子串,而非长度。

  • 最长公共子序列和最长公共子串

    最长公共子序列和最长公共子串区别 最长公共子串(Longest CommonSubstring)和最长公共子序列(...

  • 子串 子序列 总结

    最长公共子串 子串的要求比子序列严格,所以可以讨论子串的终点 最长公共子序列 DP解 递归+memo 最长公共回文...

  • LCS问题

    LCS问题包括最长公共子序列和最长公共子串,其中,最长公共子串要求必须连续。 对于二者的求解方式 最长公共子序列:...

  • 最长公共 / 对称字串

    求最长对称字串是求最长公共子串的变形.. (๑˘ ˘๑) 最长公共子串 Longest Common Subseq...

  • 字符串算法

    最长公共前缀 最长回文串 最长回文子序列 最长公共子串 反转单词顺序列 反转字符串 字符串转数字 IP-int互转

  • 06-18:刷题综合一:动态规划

    1、最长公共子串 牛客网:最长公共子串 https://www.nowcoder.com/practice/f33...

  • 每天一道算法题18

    【最长公共子序列,子串】给定两个字符串上str1 和 str2, 求两个字符的最长公共子序列和最长公共子串。 最长...

  • 两个字符串的最长公共子串

    最长公共子串(Longest Common Substring)与最长公共子序列(Longest Common S...

  • 动态规划 最长公共子串

    核心思路和最长公共子序列一样 区别在于子串必须连续 可以先看我之前这篇文章最长公共子序列问题总结 最长公共子串同样...

网友评论

    本文标题:HDU 1503 Advanced Fruits 最长公共子串应

    本文链接:https://www.haomeiwen.com/subject/nyygixtx.html