【问题标题】:How to flip/reverse a 2D array's rows or columns using STL如何使用 STL 翻转/反转二维数组的行或列
【发布时间】:2016-01-17 04:16:26
【问题描述】:

我有一个任意类型的二维数组,尺寸为N x M(即T array[N][M];),例如,

我想翻转它的,例如,

或其,例如,

如何仅使用 STL 轻松做到这一点?

【问题讨论】:

  • 一种方法是在包装矩阵的类中设置一个标志,当你反转时,切换这个标志。通过 getter 函数访问元素时,相应地更改索引计算。如果您经常交换,这会很快。然而,由于额外的标志,访问每个元素的成本略高。
  • 另外,答案取决于您如何表示数据。它是编码在 1 个平面数组中,还是一个数组数组等中?
  • @NeilKirk 一个二维数组(例如,T a[4][3])。

标签: c++ arrays c++11 multidimensional-array stl


【解决方案1】:

你可以通过使用std::reverse来做到这一点。

下面我定义了两个通用函数,即flip_columnsflip_rows,它们将任意类型的二维数组作为输入,它们分别翻转/反转其列和行。

翻转/反转二维数组列

template<typename T, std::size_t N, std::size_t M>
void flip_columns(T (&arr)[N][M]) {
  std::for_each(std::begin(arr), std::end(arr),
                [](auto &i) {std::reverse(std::begin(i), std::end(i));});
}

翻转/反转二维数组行

template<typename T, std::size_t N, std::size_t M>
void flip_rows(T (&arr)[N][M]) {
  std::reverse(std::begin(arr), std::end(arr));
}

LIVE DEMO

【讨论】:

    【解决方案2】:

    无需移动内存中的内容。一种典型的方法是定义一个遍历策略,它以指定的顺序(反转的列或反转的行)“遍历”数组,这对于我们不想弄乱的非常大的对象特别有效。

    展示了这一点,下面的助手同时“反转”了行和列:

    template<typename T, std::size_t N, std::size_t K>
    struct Rev
    {
        T(&data)[N][K];
        Rev(T(&data)[N][K]) : val(val) { }
        T& access(std::size_t row, std::size_t column) {
            return val[N - row - 1][K - column - 1];
        }
    };
    

    例子:

    int ar[2][5] = { { 1, 2, 3, 4, 5 }, { 11, 22, 33, 44, 55 } };
    
    Rev<int, 2, 5> ob(ar);
    std::cout << ob.access(1, 3); // prints 2
    

    我选择了access 方法,因为自定义operator[] 需要返回一个可索引的临时对象,并且需要多几行才能与此处显示的引用包装器一样高效;无论如何,它可以与内置数组的接口相匹配,即:

    Rev<int, 2, 5> ob(ar)
    ob[1][3]; 
    

    本着同样的精神,反向迭代器可用于循环遍历数组的切片(行或列)

    【讨论】:

      【解决方案3】:

      在二维向量中

      旋转我们使用的行 -> reverse(a[i].begin,a[i].end());

      旋转我们使用的列 -> reverse(a.begin(),a.end());

      【讨论】:

      • OP 没有使用std::vector&lt;std::vector&lt;int&gt;&gt;,他使用的是二维 C 样式数组。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      • 1970-01-01
      • 1970-01-01
      • 2018-03-03
      • 1970-01-01
      • 2020-10-21
      • 1970-01-01
      相关资源
      最近更新 更多