简体   繁体   English

如何在C ++中引用二维数组(矩阵)的列

[英]how to refer to a column of a 2D array (matrix) in C++

I have declared a 2D array in the following way (please note that I'm very beginner!) 我已经用以下方式声明了一个2D数组(请注意我是初学者!)

double **A=new double*[10];

for(int i=0;i<10;i++)
    A[i]=new double[5];

So I guess this already defines a matrix of size 10 by 5. 所以我猜这已经定义了一个10×5的矩阵。

I know that to refer to its row I can use 我知道要引用它可以使用的行

A[i]

But the question is, how to refer to a column of A? 但问题是,如何引用A列? something like A[][i]? 类似A [] [i]的东西?

You cannot access a column directly. 您无法直接访问列。

You can either access a row by A[i] (which is an array itself) or an element A[i][j] (which is a single double in your case). 您可以通过A [i](这是一个数组本身)或元素A [i] [j](在您的情况下是一个双精度)访问一行。

If you want to get a column you have to iterate throw the array 如果你想获得一个列,你必须迭代抛出数组

for(unsigned int i = 0; i < 10; i++) 
{
    A[i][2] // do something
}

Accesses the third column. 访问第三列。

So it is useful to think about if you want to create a 10x5 or a 5x10 matrix. 因此,考虑是否要创建10x5或5x10矩阵是有用的。 If you often need to work with just a row or an column, it may be a good idea to invert the array layout (here switch columns and rows) 如果您经常只需要使用行或列,那么反转数组布局(此处切换列和行)可能是个好主意

EDIT: Here is some simplified explanation: Imagine the following code 编辑:这是一些简化的解释:想象一下下面的代码

int** A = new int*[2];

for(int i=0;i<2;i++)
     A[i]=new int[3];
// more init code

Then the array in memory may look like this: 然后内存中的数组可能如下所示:

内存中的简单2D数组

So it is simple to see that the "blue row" can be accessed directly as you have its startaddress in A[0] But if you want every third element of the sub arrays you have to iterate through A and add 2 to every startadress. 所以很容易看到“蓝色行”可以直接访问,因为你在A [0]中有它的startaddress但是如果你想要子数组的每个第三个元素,你必须迭代A并为每个startadress添加2。 Especially as there is no guaranteed fixed distance in memory between the subarrays if you use heap memory via "new". 特别是如果通过“new”使用堆内存,则子阵列之间的内存中没有保证的固定距离。

But you often can speedup computations by choosing the layout of your arrays in a good way. 但是,您通常可以通过以良好的方式选择阵列的布局来加速计算。 One could for example store the second matrix transposed when implementing matrix multiplication. 例如,可以存储在实现矩阵乘法时转置的第二矩阵。

Enother way using pointers. 使用指针的另一种方式。

    // Matrix dimentions

    int n_rows = 10;
    int n_cols = 5;

    // create rows as pointers to columns 

    double **A = new double*[n_rows];

    // create columns 

    for (int i = 0; i < n_rows; i++)
    {
        A[i] = new double[n_cols];
    }

    // Fill our matrix

    int count=0;

    for (int i = 0; i < n_rows; i++)
    {
        for (int j = 0; j < n_cols; j++)
        {
            A[i][j]=count;
            ++count;
        }
    }   

    // Create pointers columns

    double ***A_t = new double**[n_cols];

    // create matrix pointers rows

    for (int i = 0; i < n_cols; i++)
    {
        A_t[i] = new double*[n_rows];
    }

    // And fill it with pointers to transposed main matrix elements
    for (int i = 0; i < n_rows; i++)
    {
        for (int j = 0; j < n_cols; j++)
        {
            A_t[j][i]=&A[i][j];
        }
    }

    // output first row/column for each case 

    for (int i = 0; i < n_cols; i++)
    {
          cout << *(A[0]+i) << endl;
    }

    cout << "-------------"<< endl;

    for (int i = 0; i < n_rows; i++)
    {
          cout << **(A_t[0]+i) << endl;
    } 

// Work with matrices here

// Don't forget to clean everything.

A 2D array looks something like this 2D数组看起来像这样

if ur 2d array is a[i][j] then i will be ur rows and j will be ur columns. 如果你的2d数组是[i] [j]那么我将是你的行,j将是你的列。

if u want to access columns of first row you can do something like this a[0][1] a[0][2] a[0][3] 如果你想访问第一行的列你可以做这样的事情a [0] [1] a [0] [2] a [0] [3]

see the link it will clear you more. 看到它会更清楚你的链接。

http://i.stack.imgur.com/21Bqr.png http://i.stack.imgur.com/21Bqr.png

Rows and columns are sort of abstracted away, you can consider the spatial orientation to go in either direction if you want (10 columns, or 5 columns if you see what I mean). 行和列是抽象的,你可以考虑空间方向,如果你想要任意方向(10列,或5列,如果你看到我的意思)。 But obviously you need to keep your use consistent. 但显然你需要保持你的使用一致。

It probably makes sense to keep the 'outer' array the column, so that A[x][y] makes sense in a cartesian coordinate type sense. 将'外部'数组保持为列可能是有意义的,因此A [x] [y]在笛卡尔坐标类型意义上是有意义的。 From your example, you want to be indexing like A[i][] (ie your i index is the column, or X coordinate). 从您的示例中,您希望像A [i] [](即您的i索引是列或X坐标)进行索引。

You cannot refer to a column in this way. 您不能以这种方式引用列。 This is because you dont really have a matrix, you specified an array of arrays. 这是因为你没有真正的矩阵,你指定了一个数组数组。 The arrays are your rows, but the columns are not directly stored. 数组是您的行,但不直接存储列。 If you want to get a whole column, you have to run through all rows, receive the value stored in that column and store it in a different array. 如果要获取整列,则必须遍历所有行,接收存储在该列中的值并将其存储在不同的数组中。

auto column = new double[10];
for(int i = 0; i < 10; i++){
    column[i] = A[i][2] //if you want to get the 2nd column
}

Elements of any row can be referred by arr[row_num][i] . 任何行的元素都可以由arr[row_num][i]引用。

Similarly elements of any column can be referred by arr[i][col_num] . 类似地,任何列的元素都可以由arr[i][col_num]

Note that indexes are zero-based in C/C++. 请注意,索引在C / C ++中从零开始。 So if your column/row size is x , i can vary from 0 to x-1 . 因此,如果您的列/行大小为x ,则i可以在0x-1

As you are a beginner, i would also like to tell you a bit more about arrays in C/C++. 由于您是初学者,我还想告诉您有关C / C ++中的数组的更多信息。 Firstly, i would suggest you to read about pointers if you are not familiar with them. 首先,如果您不熟悉指针,我建议您阅读指针。

When you declare an array, say, int arr[10], arr[0] means the first element. 当你声明一个数组时,比如int arr [10],arr [0]表示第一个元素。 Also, arr + 0 (or simply arr) means the address of the first element. 此外,arr + 0(或简称为arr)表示第一个元素的地址。 Similarly, arr[i] means ith element, arr + i means address of the ith element. 类似地,arr [i]表示第i个元素,arr + i表示第i个元素的地址。 To print the value at an address, in c/c++, you can use value-at operator, represented by (*), eg *(arr + i) will be equivalent to arr[i], ie the ith element. 要在地址中打印值,在c / c ++中,您可以使用value-at运算符,由(*)表示,例如*(arr + i)将等效于arr [i],即第i个元素。 Also, address of operator (&) gives to the address of an element, &arr[i] is equivalent to (arr + i). 另外,运算符(&)的地址给出了元素的地址,&arr [i]等价于(arr + i)。

If arr is a 2-d array, arr[i][j] means jth element of ith row. 如果arr是2-d数组,则arr [i] [j]表示第i行的第j个元素。 arr[i] means address of first element of ith row. arr [i]表示第i行的第一个元素的地址。 c/c++ are row-major, which means first row is filled first and then second and so on. c / c ++是行主要的,这意味着第一行先填充然后填充第二行,依此类推。 and we have to specify the row size always while declaring a 2-d array. 并且我们必须在声明二维数组时始终指定行大小。

Note: In pointer-arithmetic, arr+i, and arr+i+1, etc. are not being incremented by 1, but by the size of the element it is pointing to. 注意:在指针算术中,arr + i和arr + i + 1等不会增加1,而是增加它指向的元素的大小。

So, to refer to a row, we can do the following: 因此,要引用一行,我们可以执行以下操作:

//note that arr[row_num] is an address
int * new_1d_arr = arr[row_num];
for(int i = 0; i < row_size; i++)
    cout << new_1d_arr[i] << endl;

Similarly, we can also refer to an column, but it would be a bit more complex, as we will have to increment i, not by 1, but by the row_size, due to the fact that arrays in c/c++ are row-major, and we would have to skip over number of elements (equal to row_size) to get to the next element in the same column. 类似地,我们也可以引用一个列,但它会更复杂,因为我们将不得不增加i,而不是增加1,而是增加row_size,因为c / c ++中的数组是行主要的,我们必须跳过多个元素(等于row_size)才能到达同一列中的下一个元素。

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

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