我通过malloc在C中创建一个二维数组,如下所示:
double **x;
x = malloc(rows * sizeof(double*));
for (n = 0; n < rows; n++){
x[n] = malloc(columns * sizeof(double));
memset(x[n], 0, columns * sizeof(double));
}
我还检查malloc是否失败,但为了更好的可读性,我发布了该版本。它实际上工作正常。
现在我有一个函数,它按顺序排列元素:
double qsort_row_wise(double points[], int points_count)
我可以通过以下方式调用特定行(第3/4行)和4 + 1列:
my_qsort(x[3], 4);
此函数正在接收正常数组,并且运行良好。
现在我想使用此函数来排序列。这就是为什么我要搜索这样的东西(这不起作用):
my_qsort(x[][3], 4);
x [] [3]这里指的是第3列的所有元素的向量。
如果可能的话,我想做一个&#34;矢量&#34;类操作,而不是一步一步地选择所有内容(for loop)以获得最佳性能。
答案 0 :(得分:4)
由于您需要2D数组,因此最好将其分配为单个连续块:
double *x = calloc(rows * columns, sizeof(double)); // does zero init
现在您可以使用算术进行索引,因此您的my_qsort
函数应该声明为:
void my_qsort(double *start, size_t count, size_t stride);
现在要排序第3行,你可以这样做:
my_qsort(x + 3 * columns, columns, 1);
要对第5列进行排序,您可以这样做:
my_qsort(x + 5, rows, columns);
在排序过程中,您需要访问的元素为start[ii * stride]
,其中ii
从0
转到count
。当然,start
只是您希望排序的2D数组中的第一个单元格 - 通常是行中最左边的单元格或列中的顶部单元格。也可以使用相同的函数对行或列的一部分进行排序,或者通过矩阵对任意“行”进行排序,例如,方阵的对角线:
my_qsort(x, rows, columns + 1);
只需一次分配来存储您的2D数组,不仅可以简化“跨步”操作,而且效率更高,因为它减少了分配次数,改善了空间局部性,并且在Linux上增加了内存的可能性在您free
时立即回收,因为“大”分配是通过mmap
而不是sbrk
完成的。
答案 1 :(得分:2)
好吧,你需要创建一个数组,其数量大小是你有多少行,因为一列由n行组成。
double *cols = malloc(nofrows * sizeof(double));
然后遍历行上的二维数组并使用列索引作为常量:
int whichcolumn = 1;
for (int i = 0; i < rows; i++)
cols[i] = x[i][whichcolumn];
然后将cols传递给qsort函数
qsort_row_wise(cols, nofrows);
答案 2 :(得分:1)
如果可能的话,我想进行矢量操作,而不是逐步选择所有内容(for loop)以获得最佳性能。
这是不可能的。
你的第一个代码片段创建的不是2D数组,而是一个指针的一维数组,每个元素指向double
的1D数组。这种结构有时被称为“分散”数组,因为它由“行数”+1组成,不一定是连续的内存块。
从后一个事实得出结论,您无法提取列,因为元素分布在整个内存中,并且无法通过单个操作进行寻址。