【问题标题】:Wrong answer in Abbreviations problem using DP使用 DP 的缩写问题中的错误答案
【发布时间】:2021-03-12 04:29:52
【问题描述】:

谁能解释我的代码有什么问题?我在 7 个测试用例中得到“中止调用”。休息成功。

我有一个大小为 n+1 x m+1 的 2d dp 数组,其中 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]

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

附:程序的主要逻辑就在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;
}

【问题讨论】:

  • 请显示minimal reproducible example 的输入、预期输出和实际输出
  • 这段代码不是为了让其他人阅读而编写的。 llvivvi...?!?你为什么要这样做?
  • 讽刺的是,如果没有这些代码缩短技巧,您的代码会更短
  • @idclev463035818 抱歉。这只是我在 CP 中使用的一些快捷方式,所以我可以写得更快。我已经编辑了我的代码并删除了所有冗余。请再看一遍
  • @AlanBirtles 请看看代码现在是否正常。至于输入和输出,对于在hackerrank中解锁的都是正确的。问题出在那些被锁定的人身上,所以我怀疑粘贴没问题的人会有所帮助。如果您仍然需要这些,请告诉我

标签: c++ algorithm dynamic-programming


【解决方案1】:

代码中的错误是“Segmentation fault”

因为下面的循环:

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;
}

【讨论】:

  • 哦。我知道了。这就说得通了。我一直在想我的逻辑有什么问题......大声笑
  • @Ak01 如果我的回答解决了您的问题,请您接受/赞成吗?
  • 当然,没问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多