C++ 2D 数组转为 1D 数组

7
我试图将一个二维数组转换为一维数组。 我对C/C++非常陌生,但我认为学习如何将二维数组转换为一维数组非常重要。 所以在这里,我遇到了这个问题。
目前我的代码是: http://ideone.com/zvjKwP
#include<iostream>

using namespace std;

int main()
{

int n=0,m=0; // 2D array nRow, nCol
int a[n][m];
int i,j; // цикъл въвеждане 2D
int q,p,t; // for 2D=>1D
int b[100];
int r; // for cout
cout<<"Enter the array's number of rows and columns: ";
cin>>n>>m;

// entering values for the 2D array
    for (i = 0;i<=n;i++)
    {
        for (j = 0;j<=m;j++)
        {
            cout<<"a["<<i<<"]["<<j<<"]="<<endl;
            cin>>a[i][j];
            cin.ignore();
        }
    }

  // Most likely the failzone IMO
  for (q = 0;q<=i;q++)
    {
        for (t = 0;t<=i*j+j;t++)
        {
            b[t] = a[i][j];
        }
    }
    // attempting to print the 1D values
     cout<<"The values in the array are"<<"\n";
    for(r=0;r<=t;r++)
    {
        cout<<"b["<<r<<"] = "<<b[r]<<endl;
    }

    cin.get();
    return 0;
    }

我在认为自己失败的地方留下了评论。 我必须限制进入一维数组的数字,其值的平方大于50。 但是我肯定必须解决2D=>1D转换的问题。 你能帮我吗?

可变长度数组不是标准的。 - chris
2
另外,一旦您创建了数组,通过更新“n”和“m”它不会被重新调整大小。 - agbinfo
6个回答

8
你的猜测是正确的:
循环应该是这样的:
for (q = 0; q < n; q++)
{
    for (t = 0; t < m; t++)
    {
        b[q * m + t] = a[q][t];
    }
}

从更高维数组的角度考虑这样的转换会更容易。此外,使用您的代码,在b赋值循环中实际上没有修改ij,因此您不应该期望将不同的值分配给b的不同数组成员。


非常感谢。我发现我的错误并不是“巨大”的,而实际上使整个循环无效了。 - Anton Antonov
6
应该实际为 b[q*m+t] - spellmansamnesty

5

http://www.cplusplus.com/doc/tutorial/arrays/

请看“伪多维数组”章节。

我见过许多例子都没有正确地使用下标算法。如果不确定,可以跟踪它。对于一个二维数组,下标的顺序应该从0-(HEIGHT*WIDTH-1)顺序进行。

#define WIDTH 5
#define HEIGHT 3

int jimmy [HEIGHT * WIDTH];
int n,m;

int main ()
{
  for (n=0; n<HEIGHT; n++)
    for (m=0; m<WIDTH; m++)
    {
      jimmy[n*WIDTH+m]=(n+1)*(m+1);
    }
}

3

你也可以用这种方式来实现;

int singleArraySize = columns * rows;
for (int i = 0; i < singleArraySize; ++i)
    *(oneDArr + i) = *(twoDArr + i);

第二个例子利用了二维数组在内存中占用连续的空间这一事实。

所以如果你有 array[3][3] = {{1,2,3}, {4,5,6}, {7,8,9}} 在计算机内存中,它们的存储方式如下:

memory address | array[i][j] | value
---------------+-------------+---------
0x1            | array[0][0] | 1
0x2            | array[0][1] | 2
0x3            | array[0][2] | 3
0x4            | array[1][0] | 4
0x5            | array[1][1] | 5
0x6            | array[1][2] | 6
0x7            | array[2][0] | 7
0x8            | array[2][1] | 8
0x9            | array[2][2] | 9

内存地址是存储值的地址。


3

首先,1D数组的大小应为n*m

循环可以按以下方式进行-

int lim = n*m;

for(q = 0; q<lim; ++q) {

    b[q] = a[q/m][q%m];
}

我认为这个答案比被接受的答案稍微更简洁,因为它避免了嵌套循环。 - pretzlstyle

1
这段代码
int n=0,m=0; // 2D array nRow, nCol
int a[n][m];

无效。首先,维度应为常量表达式,将其设置为0没有意义。

而完成任务的更简单方法是使用指针。例如:

int *p = b;

for ( const auto &row : a )
{
    for ( int x : row ) *p++ = x;
}

1
我觉得我对C++还不是很熟悉,无法百分之百理解这段代码。抱歉!:D - Anton Antonov
没有什么难的。你应该学习所谓的基于范围的for语句。你可以用它替换你的循环,但保留使用指针作为目标变量的想法。 - Vlad from Moscow

0

这个答案使用了 C 语言的实用工具 memcpy。由于内存是连续的,因此您可以将其作为字节块进行复制:

#include <string.h> // For memcpy
#include <iostream>

int main() {
    // Fill in the 2D array with some values...
    int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};

    // Allocate the 1D array
    int b[3*3];

    // Copy into 1D array
    memcpy(b,a,9*sizeof(int));

    // Print the result
    for (int i(0); i<9; ++i) {
        std::cout << b[i] << " ";
    }
}

输出:

1 2 3 4 5 6 7 8 9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接