将阵列旋转180°,步幅为C

时间:2017-12-22 11:39:38

标签: c arrays

按照我之前更常见的问题: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]

旋转的内存视图稍后将在卷积产品中使用

1 个答案:

答案 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;
}

问题是所有这些调度和事情都不会很快。您可以将第一种和第二种方法结合起来。