按照我之前更常见的问题:How to rotate an array by ± 180° in an efficient way?
我想知道如何使用C中的内存视图或步幅将M×N数组旋转180°而不复制它,只需通过索引转换。
索引映射如下:
for (i in [0:M-1], j in [0:N-1]) do
rotated[i, N-1-j] = array[M-1-i, j]
旋转的内存视图稍后将在卷积产品中使用
答案 0 :(得分:1)
简短的回答是C中没有内存视图或步幅。
答案很长。
问题是你基本上有一大块内存。
想象一下下面的声明int arr[3][6]
这实际上意味着你有一块内存能够存储18个整数值,所以每当你做int a = arr[2][3]
这样的事情时,它基本上与int a = ((int*)arr)[2*6 + 3]
相同。因此,如果您有int arr[M][N]
,则可以将其更改为原位或复制到另一个阵列。 python中的内存视图可能会为您提供访问数据的隐式函数:
#define N 10
#define M 20
int arr[M][N];
inline int at_rotated(int size_t i, size_t j) {
return arr[M-1-i][N-1-j];
}
这可能不是你想要的,因为它迫使你坚持指定的尺寸并保持数组“全局”。
更通用的方法是。
struct arr_s {
int(*at)(struct arr_s *arr, size_t, size_t);
size_t rows;
size_t cols;
int *data;
};
int at(struct arr_s *arr, size_t i, size_t j) {
if (arr->at) return arr->at(arr, i, j);
return arr->data[i * arr->cols + j];
}
int rotated_at_(struct arr_s *arr, size_t i, size_t j) {
return arr->data[(arr->rows - 1 - i) * arr->cols + (arr->cols - 1 - j)];
}
struct arr_s rotate(struct arr_s *arr) {
struct arr_s res = *arr;
res.at = rotated_at_;
return res;
}
int main(void) {
struct arr_s some = {
.rows = 2,
.cols = 3,
.data = (int*)(int[2][3]){ { 1, 2, 3}, {4, 5, 6} },
};
int a = at(&some, 0, 2);
struct arr_s rotated = rotate(&some);
int b = at(&rotated, 0, 2);
printf("%d %d\n", a, b);
return 0;
}
问题是所有这些调度和事情都不会很快。您可以将第一种和第二种方法结合起来。