简体   繁体   English

在 C++ 中初始化二维向量的问题

[英]Problem with initialising 2D vector in C++

I was implementing a solution for this problem to get a feel for the language.我正在为这个问题实施一个解决方案,以了解该语言。 My reasoning is as follows:我的推理如下:

  1. Notice that the pattern on the diagonal is 2*n+1 .请注意,对角线上的图案是2*n+1

  2. The elements to the left and upwards are alternating arithmetic progressions or additions/subtractions of the elements from the diagonal to the boundary.左边和上面的元素是从对角线到边界的元素的交替等差数列或加法/减法。

  3. Create a 2D vector and instantiate all the diagonal elements.创建一个二维向量并实例化所有对角线元素。 Then create a dummy variable to fill in the remaining parts by add/subtract the diagonal elements.然后创建一个虚拟变量以通过添加/减去对角线元素来填充剩余部分。

My code is as follows:我的代码如下:

#include <vector>

using namespace std;

const long value = 1e9;

vector<vector<long>> spiral(value, vector<long> (value));
long temp;

void build(){
    spiral[0][0] = 1;
    for(int i = 1; i < 5e8; i++){
        spiral[i][i]= 2*i+1;
        temp = i;
        long counter = temp;
        while(counter){
            if(temp % 2 ==0){
                spiral[i][counter]++;
                spiral[counter][i]--;
                counter--;
                temp--;
            }else{
                spiral[i][counter]--;
                spiral[counter][i]++;
                counter--;
                temp--;
            }
        }
    }
}

int main(){
    spiral[0][0] = 1;
    build();
    int y, x;
    cin >> y >> x;
    cout << spiral[y][x] << endl;
}

The problem is that the programme doesn't output any thing.问题是程序不输出任何东西。 I can't figure out why my vector won't print any elements.我不明白为什么我的向量不会打印任何元素。 I've tested it with spiral[1][1] and all I get is some obscure assembler message after waiting 5 or 10 minutes.我已经用spiral[1][1]对其进行了测试,等待 5 或 10 分钟后,我得到的只是一些晦涩的汇编消息。 What's wrong with my reasoning?我的推理有什么问题?

EDIT: Full output is:编辑:完整输出是:

在此处输入图片说明

and

在此处输入图片说明

A long is probably 4 or 8 bytes for you (eg commonly 4 bytes on Windows, 4 bytes on x86 Linux, and 8 bytes on x64 Linux), so lets assume 4. 1e9 * 4 is 4 gigabytes of continuous memory for each vector<long> (value) .对于您来说, long可能是 4 或 8 个字节(例如,通常在 Windows 上为 4 个字节,在 x86 Linux 上为 4 个字节,在 x64 Linux 上为 8 个字节),因此让我们假设 4. 1e9 * 4是每个vector<long> (value) 4 GB 连续内存vector<long> (value)

Then the outer vector creates another 1e9 copies of that, which is 4 exabytes (or 4 million terabytes) given a 32bit long or double for 64bit and ignoring the overhead size of each std::vector .然后外部向量创建另一个1e9副本,这是 4 1e9字节(或 400 1e9兆字节),给定 32 位长或 64 位双倍,并忽略每个std::vector的开销大小。 It is highly unlikely that you have that much memory and swapfile, and being a global this is attempted before main() is called .您不太可能拥有那么多内存和交换文件,并且在调用 main() 之前尝试将其设为全局。

So you are not going to be able to store all this data directly, you will need to think about what data actually needs to be stored to get the result you desire.因此,您将无法直接存储所有这些数据,您需要考虑实际需要存储哪些数据才能获得所需的结果。


If you run under a debugger set to stop on exceptions, you might see a std::bad_alloc getting thrown, with the call stack indicating the cause (eg Visual Studio will display something like "dynamic initializer for 'spiral'" in the call stack), but it is possible on Linux the OS will just kill it first, as Linux can over-commit memory (so new etc. succeeds), then when some program goes to use memory (an actual read or write) it fails (over committed, nothing free) and it SIGKILL's something to free memory (this doesn't seem entirely predictable, I copy-pasted your code onto Ubuntu 18 and on command line got "terminate called after throwing an instance of 'std::bad_alloc'").如果您在设置为停止异常的调试器下运行,您可能会看到std::bad_alloc被抛出,调用堆栈指示原因(例如,Visual Studio 将在调用堆栈中显示类似“'spiral'的动态初始化程序”的内容),但在 Linux 上操作系统可能会先杀死它,因为 Linux 可能会过度使用内存(所以new等成功),然后当某个程序开始使用内存(实际读取或写入)时,它会失败(超过提交,没有什么免费的)并且它 SIGKILL 是释放内存的东西(这似乎并不完全可以预测,我将您的代码复制粘贴到 Ubuntu 18 上,并且在命令行上“在抛出一个‘std::bad_alloc’实例后被终止调用” )。

Math is your friend, here, not std::vector .在这里,数学是你的朋友,而不是std::vector One of the constraints of this puzzle is a memory limit of 512MB, but a vector big enough for all the tests would require several GB of memory.这个谜题的一个限制是 512MB 的内存限制,但是一个足够大的向量进行所有测试需要几 GB 的内存。

Consider how the square is filled.考虑如何填充正方形。 If you choose the maximum between the given x and y (call it w ), you have "delimited" a square of size w 2 .如果您选择给定xy之间的最大值(称为w ),您就“分隔”了一个大小为 w 2的正方形。 Now you have to consider the outer edge of this square to find the actual index.现在您必须考虑这个正方形的外边缘才能找到实际的索引。

Eg Take x = 6 and y = 3. The maximum is 6 (even, remember the zig zag pattern), so the number is (6 - 1) 2 + 3 = 28例如,取 x = 6 和 y = 3。最大值是 6(偶数,记住锯齿形图案),所以数字是 (6 - 1) 2 + 3 = 28

*  *  *  *  *  26 
 *  *  *  *  *  27
 *  *  *  *  * [28] 
 *  *  *  *  *  29
 *  *  *  *  *  30
36 35 34 33 32  31

Here , a proof of concept.在这里,一个概念证明。

The problem actually asks you to find an analytical formula for the solution, not to simulate the pattern.该问题实际上要求您找到解决方案的分析公式,而不是模拟模式。 All you need to do is to carefully analyze the pattern:您需要做的就是仔细分析模式:

unsigned int get_n(unsigned int row, unsigned int col) {
    assert(row >= 1 && col >= 1);

    const auto n = std::max(row, col);
    if (n % 2 == 0)
        std::swap(row, col);
    if (col == n)
        return n * n + 1 - row;
    else
        return (n - 1) * (n - 1) + col;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM