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
posted @ 2018-05-19 12:36  悠悠呦~  阅读(276)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end