📌  相关文章
📜  教资会网络 | UGC NET CS 2014 年 12 月 – III |问题 44(1)

📅  最后修改于: 2023-12-03 15:26:02.798000             🧑  作者: Mango

UGC NET CS 2014年12月 - III | 问题44

这是一道有关于编程的问题,适合所有程序员。在本题中,我们将讨论如何使用C++编写程序以在控制台中输出最大公共子串(LCS)。

问题描述

给定两个字符串,找到它们之间的最大公共子串。

解决方案

我们可以使用动态规划来解决该问题。定义一个二维数组dp[i][j],表示第一个字符串中前i个字符和第二个字符串中前j个字符的LCS的长度。则状态转移方程为:

if (str1[i - 1] == str2[j - 1]) {
    dp[i][j] = dp[i - 1][j - 1] + 1;
}
else {
    dp[i][j] = 0;
}

LCS的长度即为dp[i][j]数组中的最大值。

以下是C++代码实现:

#include <iostream>
#include <cstring>
using namespace std;

int main() {
    string str1, str2;
    cin >> str1 >> str2;

    int n = str1.length(), m = str2.length();
    int dp[n + 1][m + 1];
    memset(dp, 0, sizeof(dp));
    int maxLen = 0, endIndex = 0;
    
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (str1[i - 1] == str2[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
                if (dp[i][j] > maxLen) {
                    maxLen = dp[i][j];
                    endIndex = i - 1;
                }
            }
            else {
                dp[i][j] = 0;
            }
        }
    }

    cout << str1.substr(endIndex - maxLen + 1, maxLen) << endl;
    return 0;
}
代码说明

首先我们读入两个字符串str1str2。然后创建二维数组dp,并将其所有元素初始化为0。接着,使用两个for循环遍历字符串str1str2,并更新dp数组中的元素,使用maxLen变量记录LCS的长度,使用endIndex变量记录LCS在第一个字符串中的结束下标。在数组更新的过程中,如果我们发现一个新的LCS长度(即dp[i][j])比已记录的长度还要大,则更新maxLenendIndex的值。最后,我们使用endIndexmaxLen计算出LCS的起始下标,并在第一个字符串中截取出LCS并输出。

结论

以上是使用动态规划来计算两个字符串的LCS的C++实现方法。这种算法的时间复杂度为$O(n^2)$,可以在面对较小规模的问题时使用。