gpt4 book ai didi

c - 将 2D 数组 reshape 为 3D 数组 C

转载 作者:行者123 更新时间:2023-11-30 14:51:06 26 4
gpt4 key购买 nike

您好,我正在尝试将 matlab 代码转换为 C 语言。在执行此操作时,我必须将 2d 数组 reshape 为 3d 数组。我尝试编写一个函数,如下所示。我得到了here的帮助.

#include <stdio.h>
#include <stdlib.h>

#define ZALLOC(item, n, type) if ((item = (type *)calloc((n), sizeof(type))) == NULL) \
fatalx("Unable to allocate %d unit(s) for item\n", n)
int i,j,k,x,y;
static void fatalx(const char *str, size_t n)
{
fprintf(stderr, "%s: %zu\n", str, n);
exit(1);
}

static int ***alloc_3d(int ar[][12],int rows, int cols,int levels)
{

int count = 0;
int ***array_3d;
ZALLOC(array_3d, levels, int **);
for (i = 0; i < levels; i++)
{
int **data;
ZALLOC(data, rows, int *);
array_3d[i] = data;
for (j = 0; j < rows; j++)
{
int *entries;
ZALLOC(entries, cols, int);
array_3d[i][j] = entries;
for (k = 0; k < cols; k++)
{
array_3d[i][j][k] = ar[i][j];
}
}
}
return array_3d;
}

static void print_3d(int ***a3d, int rows, int cols,int levels)
{
for (i = 0; i < levels; i++)
{
printf("%d:\n", i);
for (j = 0; j < rows; j++)
{
printf(" %d: ", j);
for (k = 0; k < cols; k++)
printf(" %3d", a3d[i][j][k]);
putchar('\n');
}
}
}

static void free_3d(int ***a3d, int levels, int rows)
{
for (i = 0; i < levels; i++)
{
for (j = 0; j < rows; j++)
free(a3d[i][j]);
free(a3d[i]);
}
free(a3d);
}

int main(void)
{
int ar[2][12]={
{1,2,3,4,5,6,7,8,9,10,11,12},
{13,14,15,16,17,18,19,20,21,22,23,24}
};
int d1 = 2;
int d2 = 3;
int d3 = 4;
int ***a3d = alloc_3d(ar,d1, d2, d3);

print_3d(a3d, d1, d2, d3);
free_3d(a3d, d3, d2);

return(0);
}

这不仅给了我错误的值,而且还给了垃圾值。其中第一个切片的 matlab 输出为:

a3d(:,:,1) =

 1     2     3
13 14 15

我的完全不一样

0:
0: 1 1 1
1: 2 2 2
1:
0: 13 13 13
1: 14 14 14
2:
0: 1991011277 1991011277 1991011277
1: 4 4 4
3:
0: 1 1 1
1: 6630248 6630248 6630248

正如你所看到的,也有垃圾值(value)。所以我的索引也是错误的。知道如何正确地做到这一点吗?提前致谢。

最佳答案

事实上,您的示例并未执行 reshape ,因为它创建了一个与原始数组类型完全不同的复合对象。

C 多维数组是数组的数组(数组的数组...)。除了其他重要特征之外,此类数组的所有元素在内存中都是连续的。您还可以构造一个指针数组,并将每个指针初始化为指向其自己的数组,等等。虽然这些类型的对象表面上很相似,因为您可以以大致相同的方式将索引运算符应用于两者,重要的是要理解:

  • 指针数组需要额外的空间来容纳指针,超出它们所指向的空间。
  • 虽然指针数组中的指针在内存中是连续的,但它们所指向的数组可能不是连续的。这往往会导致
    • 如果系统的页面大小不能均匀地划分指向的数组的大小,则会浪费空间,并且
    • 由于引用位置较差,访问数组元素的性能较差。
  • 指针数组更困惑且分配速度更慢,因为需要多次单独调用内存分配函数。
  • 指针数组更困惑且释放速度更慢,因为所有指向的数组也必须单独释放。
  • 另一方面,如果(指向的)成员数组的长度不完全相同,则指针数组可容纳“参差不齐”的多维伪数组。

以下是使用标准 C 多维数组(== 数组的数组)编写的程序的外观:

#include <stdlib.h>
#include <stdio.h>

#define ALLOC(p, n) do { \
if (!((p) = calloc((n), sizeof(*(p))))) { \
fprintf(stderr, "Memory allocation failure\n"); \
exit(1); \
} \
} while (0)

void *reshape_2d_3d(size_t id1, size_t id2, int iar[][id2],
size_t od1, size_t od2, size_t od3) {
// oar is a pointer to a multidimensional array; in this case, it will
// point to the first element of an array of arrays (of arrays).
int (*oar)[od2][od3];
size_t size1 = id1 * id2;
size_t size2 = od1 * od2 * od3;
size_t min_size = (size1 <= size2) ? size1 : size2;

ALLOC(oar, od1);

// A loop nest could be used here, too, but I find this simpler for
// tracking the correspondence of array elements. It also better
// accommodates the case where the reshaped result has different overall
// size from the original.
for (size_t i = 0; i < min_size; i++) {
oar[i / (od2 * od3)][(i / od3) % od2][i % od3] = iar[i / id2][i % id2];
}

return oar;
}

void print_3d(size_t levels, size_t rows, size_t cols, int ar[][rows][cols]) {
for (int i = 0; i < levels; i++) {
printf("%d:\n", i);
for (int j = 0; j < rows; j++) {
printf(" %d: ", j);
for (int k = 0; k < cols; k++) {
printf(" %3d", ar[i][j][k]);
}
putchar('\n');
}
}
}

int main(void) {
int ar[2][12] = {
{1,2,3,4,5,6,7,8,9,10,11,12},
{13,14,15,16,17,18,19,20,21,22,23,24}
};
int d1 = 2, d2 = 3, d3 = 4;
int (*a3d)[d2][d3] = reshape_2d_3d(2, 12, ar, d1, d2, d3);

print_3d(d1, d2, d3, a3d);

// A single, simple free() is all that's needed
free(a3d);
}

输出:

0:
0: 1 2 3 4
1: 5 6 7 8
2: 9 10 11 12
1:
0: 13 14 15 16
1: 17 18 19 20
2: 21 22 23 24

请注意,它使用可变长度数组,但无需通常关注堆栈分配。因此,它需要一个符合标准的 C99 编译器,或一个实现 VLA 可选(在该版本中)功能的符合标准的 C2011 编译器。

关于c - 将 2D 数组 reshape 为 3D 数组 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48526453/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com