zoukankan      html  css  js  c++  java
  • HDU 1503【LCS】(字符串合并输出)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1503

    题目大意:

    给两个字符串,组成一个长度尽可能小的字符串,它包含上述两个字符串,且原字符串中的字符在该串中的相对位置不变。

    Sample Input
    apple peach
    ananas banana
    pear peach
     
    Sample Output
    appleach
    bananas
    pearch
     
    解题思路:
    要结合样例来理解题意,本题主要难在如何输出题目要求字符串,这就需要我们仔细研究样例,去发掘它是如何输出的,具体操作见代码。
     
    #include <iostream>
    #include <string>
    #include <cstdio>
    using namespace std;
    int dp[110][110];
    int vis[110][110];      //标记路径
    int loca[110], locb[110];     //记录下最长公共子序列在这两个字符串中的位置
    int lena, lenb;   //a,b序列的长度
    int len;       //记录下最长公共子序列长度
    string stra, strb;
    
    void locallcs(int i, int j)        //标记好最长公共子序列的每一个字符分别在a,b字符中的位置
    {
        len = 0;
        while (i>0&&j>0)
        {
            if (vis[i][j] == 1)
            {
                loca[len] = i-1;      // 此时loca,locb数组记录的是最长公共子序列分别在啊a,b字符串中的位置
                locb[len] = j-1;      //不过要注意此时记录的是逆序的,这个仔细看它存入的顺序就能明白
                len++;
                i--, j--;
            }
            else if (vis[i][j] == 2)j--;
            else
                i--;
        }
    }
    
    void output()        //输出答案,至于为什么是这样输出,自己仔细研究题目的输出样例就能发现
    {
        int inverse = len - 1;
        int cur1 = 0,cur2=0;
        while (inverse >= 0)
        {
            for (int i = cur1; i<loca[inverse]; i++)              //输出a中两个相邻的公共子序列字符之间的字符
                printf("%c", stra[i]);
            for (int j = cur2; j < locb[inverse]; j++)
                printf("%c", strb[j]);
            printf("%c", stra[loca[inverse]]);    //输出那个公共字符
            cur1 = loca[inverse]+1, cur2=locb[inverse]+1;
            inverse--;
        }
        for (int i = loca[0]+1; i < lena; i++)printf("%c", stra[i]);      //输出最后一个公共子序列字符之后的字符
        for (int j = locb[0]+1; j < lenb; j++)printf("%c", strb[j]);
        cout << endl;
    }
    
    
    int main()
    {
        while (cin >> stra >> strb)
        {
            lena = stra.length();
            lenb = strb.length();
            for (int i = 0; i <= lena; i++)
            {
                for (int j = 0; j <= lenb; j++)
                {
                    if (!i || !j) {
                        dp[i][j] = 0; continue;
                    }
                    if (stra[i - 1] == strb[j - 1])
                    {
                        dp[i][j] = dp[i - 1][j - 1] + 1;
                        vis[i][j] = 1;              //标记输出路径
                    }
                    else if (dp[i - 1][j] < dp[i][j - 1])     //dp数组在本题起控制标记路径方向的作用
                    {
                        dp[i][j] = dp[i][j - 1];
                        vis[i][j] = 2;
                    }
                    else {
                        dp[i][j] = dp[i - 1][j];
                        vis[i][j] = 3;
                    }
                }
            }
            locallcs(lena, lenb);
            output();
        }
        return 0;
    }
     
    2018-05-19
  • 相关阅读:
    docker安装kafka
    Prometheus警报
    MongoDB介绍
    SpringMvc中几个注解
    无DNS安装VCSA
    互联网本质
    什么是领导力
    58沈剑_一分钟专栏
    以数据库思维理解区块链
    区块链的4个实际应用
  • 原文地址:https://www.cnblogs.com/00isok/p/9059999.html
Copyright © 2011-2022 走看看