博客
关于我
Advanced Fruits (LSC算法例题)
阅读量:272 次
发布时间:2019-03-01

本文共 2230 字,大约阅读时间需要 7 分钟。

21st Century Fruits公司专注于通过基因转移创造新的水果种类,往往失败,但有时会产生极为罕见的新品,这些新品的味道是两种水果的结合。公司内部的讨论重点之一就是“如何命名新品”。比如,将苹果和梨混合,可以直接叫“苹果梨”,但听起来缺乏趣味。因此,公司决定使用最短的字符串,将两个水果的名字作为子序列存在。例如,“applear”既包含“苹果”(APPLEar)又包含“梨”(apPlEAR),并且没有比这更短的满足条件的字符串。

对于柑橘和boysenberry的结合,新的名字可以是“boysecranberry”或“craboysenberry”等。你的任务是编写一个程序,计算这样的最短名字。算法需要高效,否则在处理长水果名称时可能无法在规定时间内完成。

输入

每行输入包含两个字符串,表示需要结合的水果名称。所有名称的最大长度为100,只包含字母。输入结束于文件结束。

输出

对于每个测试用例,输出最短的名称。如果有多个最短的名字,任何一个都可以。

示例输入

apple peachananas bananapear peach

示例输出

appleachbananaspeach

解题思路

这个问题实际上是寻找两个字符串的最长公共子序列(LCS)。LCS是一条既包含第一个字符串中的某些字符序列,又包含第二个字符串中某些字符序列的序列。我们可以使用动态规划算法来计算LCS,然后将两个字符串中的字符按照LCS的顺序合并,得到最短的新名称。

具体来说,我们可以创建一个二维数组dp,其中dp[i][j]表示第一个字符串的前i个字符和第二个字符串的前j个字符的最长公共子序列的长度。同时,我们可以创建一个方向数组dir来记录每个位置的字符来自第一个字符串还是第二个字符串。

然后,我们可以按照LCS的结果,将两个字符串中的字符按照记录的顺序合并,生成最短的新名称。

代码实现

#include 
#include
#include
#include
using namespace std;void LCS_length(string x, string y, vector
>& dp, vector
>& dir) { int m = x.size(); int n = y.size(); dp.resize(m + 1); dir.resize(m + 1); for (int i = 0; i <= m; ++i) { dp[i].resize(n + 1); dir[i].resize(n + 1); } for (int i = 1; i <= m; ++i) { for (int j = 1; j <= n; ++j) { if (x[i-1] == y[j-1]) { dp[i][j] = dp[i-1][j-1] + 1; dir[i][j] = 'c'; } else if (dp[i-1][j] > dp[i][j-1]) { dp[i][j] = dp[i-1][j]; dir[i][j] = 'u'; } else { dp[i][j] = dp[i][j-1]; dir[i][j] = 'l'; } } }}void dp_print_lcs(const vector
>& dir, const string& x, const string& y, int i, int j) { if (i == 0 && j == 0) return; if (dir[i][j] == 'c') { dp_print_lcs(dir, x, y, i-1, j-1); cout << x[i-1]; } else if (dir[i][j] == 'u') { dp_print_lcs(dir, x, y, i-1, j); cout << y[j-1]; dp_print_lcs(dir, x, y, i, j-1); }}int main() { string x, y; while (cin >> x >> y) { vector
> dp(m + 1, vector
(n + 1, 0)); vector
> dir(m + 1, vector
(n + 1, '\0')); LCS_length(x, y, dp, dir); string result; if (dir[m][n] > 0) { dp_print_lcs(dir, x, y, m, n); } cout << result << endl; }}

代码解释

  • LCS_length函数:这个函数使用动态规划算法计算两个字符串的最长公共子序列长度,并记录每个位置的字符来源。
  • dp_print_lcs函数:这个函数根据方向数组dir的记录,按照LCS顺序输出结果字符串。
  • main函数:读取输入,调用LCS计算函数,并根据结果输出最短名称。
  • 这个算法的时间复杂度是O(m*n),其中m和n是两个字符串的长度。由于水果名称的最大长度为100,该算法在时间和空间上都是高效的,能够在规定时间内处理所有输入。

    转载地址:http://ygta.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现multi level feedback queue多级反馈队列算法(附完整源码)
    查看>>
    Objective-C实现multilayer perceptron classifier多层感知器分类器算法(附完整源码)
    查看>>
    Objective-C实现multiplesThreeAndFive三或五倍数的算法 (附完整源码)
    查看>>
    Objective-C实现n body simulationn体模拟算法(附完整源码)
    查看>>
    Objective-C实现naive string search字符串搜索算法(附完整源码)
    查看>>
    Objective-C实现natural sort自然排序算法(附完整源码)
    查看>>
    Objective-C实现nested brackets嵌套括号算法(附完整源码)
    查看>>
    Objective-C实现nevilles method多项式插值算法(附完整源码)
    查看>>
    Objective-C实现newton raphson牛顿-拉夫森算法(附完整源码)
    查看>>
    Objective-C实现newtons second law of motion牛顿第二运动定律算法(附完整源码)
    查看>>
    Objective-C实现newton_forward_interpolation牛顿前插算法(附完整源码)
    查看>>
    Objective-C实现newton_raphson牛顿拉夫森算法(附完整源码)
    查看>>
    Objective-C实现NLP中文分词(附完整源码)
    查看>>
    Objective-C实现NLP中文分词(附完整源码)
    查看>>
    Objective-C实现NMS非极大值抑制(附完整源码)
    查看>>
    Objective-C实现NMS非极大值抑制(附完整源码)
    查看>>
    Objective-C实现Node.Js中生成一个UUID/GUID算法(附完整源码)
    查看>>
    Objective-C实现not gate非门算法(附完整源码)
    查看>>
    Objective-C实现number of digits解字符数算法(附完整源码)
    查看>>
    Objective-C实现NumberOfIslands岛屿的个数算法(附完整源码)
    查看>>