题目链接: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
原文地址:https://www.cnblogs.com/00isok/p/9059999.html
时间: 2024-10-10 08:25:04