[英]how to refer to a column of a 2D array (matrix) in C++
我已经用以下方式声明了一个2D数组(请注意我是初学者!)
double **A=new double*[10];
for(int i=0;i<10;i++)
A[i]=new double[5];
所以我猜这已经定义了一个10×5的矩阵。
我知道要引用它可以使用的行
A[i]
但问题是,如何引用A列? 类似A [] [i]的东西?
您无法直接访问列。
您可以通过A [i](这是一个数组本身)或元素A [i] [j](在您的情况下是一个双精度)访问一行。
如果你想获得一个列,你必须迭代抛出数组
for(unsigned int i = 0; i < 10; i++)
{
A[i][2] // do something
}
访问第三列。
因此,考虑是否要创建10x5或5x10矩阵是有用的。 如果您经常只需要使用行或列,那么反转数组布局(此处切换列和行)可能是个好主意
编辑:这是一些简化的解释:想象一下下面的代码
int** A = new int*[2];
for(int i=0;i<2;i++)
A[i]=new int[3];
// more init code
然后内存中的数组可能如下所示:
所以很容易看到“蓝色行”可以直接访问,因为你在A [0]中有它的startaddress但是如果你想要子数组的每个第三个元素,你必须迭代A并为每个startadress添加2。 特别是如果通过“new”使用堆内存,则子阵列之间的内存中没有保证的固定距离。
但是,您通常可以通过以良好的方式选择阵列的布局来加速计算。 例如,可以存储在实现矩阵乘法时转置的第二矩阵。
使用指针的另一种方式。
// 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.
2D数组看起来像这样
如果你的2d数组是[i] [j]那么我将是你的行,j将是你的列。
如果你想访问第一行的列你可以做这样的事情a [0] [1] a [0] [2] a [0] [3]
看到它会更清楚你的链接。
行和列是抽象的,你可以考虑空间方向,如果你想要任意方向(10列,或5列,如果你看到我的意思)。 但显然你需要保持你的使用一致。
将'外部'数组保持为列可能是有意义的,因此A [x] [y]在笛卡尔坐标类型意义上是有意义的。 从您的示例中,您希望像A [i] [](即您的i索引是列或X坐标)进行索引。
您不能以这种方式引用列。 这是因为你没有真正的矩阵,你指定了一个数组数组。 数组是您的行,但不直接存储列。 如果要获取整列,则必须遍历所有行,接收存储在该列中的值并将其存储在不同的数组中。
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
}
任何行的元素都可以由arr[row_num][i]
引用。
类似地,任何列的元素都可以由arr[i][col_num]
。
请注意,索引在C / C ++中从零开始。 因此,如果您的列/行大小为x
,则i
可以在0
到x-1
。
由于您是初学者,我还想告诉您有关C / C ++中的数组的更多信息。 首先,如果您不熟悉指针,我建议您阅读指针。
当你声明一个数组时,比如int arr [10],arr [0]表示第一个元素。 此外,arr + 0(或简称为arr)表示第一个元素的地址。 类似地,arr [i]表示第i个元素,arr + i表示第i个元素的地址。 要在地址中打印值,在c / c ++中,您可以使用value-at运算符,由(*)表示,例如*(arr + i)将等效于arr [i],即第i个元素。 另外,运算符(&)的地址给出了元素的地址,&arr [i]等价于(arr + i)。
如果arr是2-d数组,则arr [i] [j]表示第i行的第j个元素。 arr [i]表示第i行的第一个元素的地址。 c / c ++是行主要的,这意味着第一行先填充然后填充第二行,依此类推。 并且我们必须在声明二维数组时始终指定行大小。
注意:在指针算术中,arr + i和arr + i + 1等不会增加1,而是增加它指向的元素的大小。
因此,要引用一行,我们可以执行以下操作:
//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;
类似地,我们也可以引用一个列,但它会更复杂,因为我们将不得不增加i,而不是增加1,而是增加row_size,因为c / c ++中的数组是行主要的,我们必须跳过多个元素(等于row_size)才能到达同一列中的下一个元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.