【问题标题】:How Vector allocation using push_back() and pop_back operation gives garbage values使用 push_back() 和 pop_back 操作的向量分配如何给出垃圾值
【发布时间】:2019-04-08 15:18:16
【问题描述】:

我正在解决一个问题,我必须从数组中找到总和最大的元素。但是有一个条件是没有两个相邻元素可以成为该最大子数组的一部分。这是我使用简单蛮力解决方案的代码-

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int t;
    cin >> t;
    while (t != 0)
    {
        int n, i, s, k = 0, m = -1001;
        vector< int > a;
        cin >> n;
        a.resize(n, 0);
        vector< int > b;
        for (i = 0; i < n; i++)
        {
            cin >> a[i];
            m = max(m, a[i]);
            if (a[i] < 0)
            {
                a[i] = 0;
                ++k;
            }
        }
        if (k == n)
            cout << m;
        else
        {
            k = 0;
            s = a[0];
            b.push_back(a[0]);
            for (i = 1; i < n; i++)
            {
                if (i != k + 1)
                {
                    if (a[i])
                    {
                        s += a[i];
                        b.push_back(a[i]);
                        k = i;
                    }
                }
                else
                {
                    if (s - a[i - 1] + a[i] > s)
                    {
                        b.pop_back();
                        s -= a[i - 1];
                        s += a[i];

                        b.push_back(a[i]);

                        ++k;
                    }
                }
            }
        }
        cout << endl;
        for (i = n; i >= 0; i--)
        {
            if (b[i])
                cout << b[i] << " ";
        }
        cout << endl;
        --t;
    }
    return 0;
}

这是代码的输入- 第一行代表没有。测试用例, 第二行表示数组的大小 下一行显示数组元素。m

5
5
-1 7 8 -5 4 
4
3 2 1 -1 
4
11 12 -2 -1 
4
4 5 4 3 
4
5 10 4 -1

输出-

4 8 
32 32607 -787829912 1 3 
32 32607 -787829912 12 
3 5 
10 

预期输出-

4 8
1 3
12
3 5
10

所以,有 5 个测试用例。对于第一个测试用例和最后两个测试用例输出是正确的。但是对于第二个和第三个测试用例,它给出了垃圾值。有什么问题,对于某些测试用例,它给出了垃圾值,而对于另一些则没有。

【问题讨论】:

  • 无关:不要使用#include &lt;bits/stdc++.h&gt;(why),避免使用using namespace std;(why)。它们共同强化了教导他人最坏的影响,并可能导致真正令人讨厌和难以理解的错误。
  • 是的,请将代码分成4个功能:读入一个测试用例,解决测试用例,打印答案和执行N个循环的主要功能。
  • 问题是什么,对于某些测试用例,它给出了垃圾值,而对于其他的则没有。我建议调试您的代码以获得产生的最小样本垃圾。
  • 似乎在打印时,您应该根据b 的大小而不是n 进行迭代。我看不出有什么可以确保b 的大小是n。也许您打算让if (b[i]) 检查b 是否有ith 元素?相反,它会检查该元素是否为零,即使它不存在(这是未定义的行为)。
  • 将所有ab 的访问权限从a[i] 更改为a.at(i),然后当您超出向量大小时,您将看到超出范围的异常。

标签: c++ vector garbage push-back


【解决方案1】:
    for (i = n; i >= 0; i--)
    {
        if (b[i])
            cout << b[i] << " ";
    }

这会打印出b 中的n+1 值。但即使在最好的情况下,b 也只有n 值(对于n=1)。而对于n&gt;1b.size() 小于n,因此您正在从向量存储之外读取垃圾(这是未定义行为)。只需使用正确的界限:

for (i = b.size() - 1; i >= 0; ++i)

【讨论】:

  • 谢谢,它正在工作。但我的疑问仍然不清楚。为什么只针对第二个和第三个测试用例而不是全部。
  • 首先,这是未定义的行为。据您所知,您的计算机可能会停止并着火。也就是说,您正在读取未初始化的内存。如果你“幸运”,你会在那里找到0s,你的支票会让它看起来一切都很好。去掉if (b[i]),你会发现它总是打印太多的值(很明显)。但有时你“倒霉”,你读到的随机内存不是零。如果您想了解更多详细信息,可以查看生成的程序集和原因,其他一切都毫无意义。
【解决方案2】:

我想我找到了你的(第一个)问题:

if(k==n)
cout<<m;

当所有数字都是负数时,这会输出其中最大的一个。

但空数组的和为 0 且大于负数且其中没有 2 个相邻的成员。所以显然正确的答案应该是 0,而不是 m。

【讨论】:

  • 对不起,但我的问题是为什么它在第二个和第三个测试用例中给出垃圾值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
相关资源
最近更新 更多