使用 DP 的缩写问题中的错误答案

Wrong answer in Abbreviations problem using DP

有人可以解释我的代码有什么问题吗?我在 7 个测试用例中收到“Abort called”。其余成功。

我有一个二维 dp 数组,其大小为:n+1 x m+1 其中 n 和 m 分别是 a 和 b 的大小。因此,行代表字符串 a,列代表字符串 b。

首先,我将 dp[0][0] 设置为 1,因为可以将空字符串变成空字符串。

所以,最初,我正在检查是否可以将 a 的任何子字符串转换为空字符串(在第一个 for 循环中)。对于没有任何大写字母的 a 的所有子字符串都是如此。只要有一个大写字母,其余的子串就不能转换了。

然后(在下一个双 for 循环中),我正在检查所有情况。

情况 1:a[i-1] == b[i-1] -> 如果两个字母完全相同,则 dp[i][j ] = dp[i-1][j-1]

案例 2:a[i-1] 是小写(这有 2 个子案例):

情况 2.1: a[i-1] 和 b[j-1] 是相同的字母(但不是相同的大小写)-> 那么我们可以改变 a [i-1] 或删除它。所以: dp[i][j] = dp[i-1][j-1] || dp[i-1][j].
情况2.2:a[i-1]和b[j-1]不相同->在这种情况下,我们只能删除a[i-1],因为它较低案件 。所以:dp[i][j] = dp[i-1][j]

Link 问题:https://www.hackerrank.com/challenges/abbr/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=dynamic-programming

P.S。程序的主要逻辑就在abbreviation()函数里面。

代码(已编辑):

#include <bits/stdc++.h>
using namespace std;

bool isSame(const char &a, const char &b)
{
    return a == b || abs(a - b) == 32;
}

bool isLower(const char &a)
{
    return a > 90 && a < 123;
}
// Complete the abbreviation function below.
string abbreviation(const string &a, const string &b)
{

    int n = a.size(), m = b.size();
    if (m > n)
        return "NO";
    vector<vector<bool>> dp(n + 1, vector<bool>(m + 1, 0));
    dp[0][0] = 1;

    for (int i = 1; i <= n; ++i)
    {
        if (isLower(a[i - 1]) && dp[i - 1][0])
            dp[i][0] = 1;
    }

    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= i; ++j)
        {
            if (a[i - 1] == b[j - 1])
                dp[i][j] = dp[i - 1][j - 1];
            if (isLower(a[i - 1]))
            {
                if (isSame(a[i - 1], b[j - 1]))
                    dp[i][j] = dp[i - 1][j - 1] || dp[i - 1][j];
                else if (dp[i - 1][j])
                {
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
    }
    return dp[n][m] ? "YES" : "NO";
}

int main()
{

    int t;
    cin >> t;

    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    while (t--)
    {
        string a, b;
        getline(cin, a);
        getline(cin, b);
        cout << abbreviation(a, b) << "\n";
    }

    return 0;
}

代码中的错误是“分段错误”

因为下面的循环:

for (int j = 1; j <= i; ++j)

因为循环迭代直到 i(它可能大于 m,即 b 的大小)。这就是 分段错误 的原因。

现在下面的代码通过了所有的测试用例。

#include <bits/stdc++.h>
using namespace std;

bool isSame(const char&a, const char&b){
    return a==b || abs(a-b)==32;
}

bool isLower(const char&a){
    return a >90 && a<123;
}

// Complete the abbreviation function below.
string abbreviation(string a, string b) {
    
    int n = a.size(), m = b.size();
    
    if(m>n)
        return "NO";
    
    int dp[n+1][m+1] = {};
    dp[0][0] = 1;
    
    for(int i=1; i<=n; ++i)
        if(isLower(a[i-1]) && dp[i-1][0]) 
            dp[i][0] = 1;
    
    for(int i=1; i<=n; ++i)
        for(int j =1; j<=min(i,m); ++j){
            if(a[i-1]==b[j-1]) 
                dp[i][j] = dp[i-1][j-1];
            if(isLower(a[i-1]))
            {
                if(isSame(a[i-1], b[j-1])) 
                    dp[i][j] = dp[i-1][j-1] || dp[i-1][j];
                else if(dp[i-1][j]) 
                    dp[i][j] = dp[i-1][j];
            }
            
        }

    return dp[n][m] ? "YES" : "NO";
}

int main()
{

    int q;
    cin >> q;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    for (int q_itr = 0; q_itr < q; q_itr++) {
        string a;
        getline(cin, a);

        string b;
        getline(cin, b);

        string result = abbreviation(a, b);

         cout << result << "\n";
    }

    return 0;
}