c++ - 按特定顺序迭代数组元素

标签 c++ arrays vector data-structures

我试图以特定顺序迭代一个一维数组/整数 vector ,但我无法围绕它来获得正确的循环条件。

输入数据是一维整数 vector :

{1, 5, 9, 13, 17, 21, 2, 6, 10, 14, 18, 22, 3, 7, 11, 15, 19, 23, 4, 8, 12, 16, 20, 24, 25, 29, 33, 37, 41, 45, 26, 30, 34, 38, 42, 46, 27, 31, 35, 39, 43, 47, 28, 32, 36, 40, 44, 48}

此输入数据本质上是具有子组的二维数组/网格的一维表示:
+----+----+----+----+----+----+
| 1  | 5  | 9  | 13 | 17 | 21 |
+----+----+----+----+----+----+
| 2  | 6  | 10 | 14 | 18 | 22 |
+----+----+----+----+----+----+
| 3  | 7  | 11 | 15 | 19 | 23 |
+----+----+----+----+----+----+
| 4  | 8  | 12 | 16 | 20 | 24 |
+----+----+----+----+----+----+
| 25 | 29 | 33 | 37 | 41 | 45 |
+----+----+----+----+----+----+
| 26 | 30 | 34 | 38 | 42 | 46 |
+----+----+----+----+----+----+
| 27 | 31 | 35 | 39 | 43 | 47 |
+----+----+----+----+----+----+
| 28 | 32 | 36 | 40 | 44 | 48 |
+----+----+----+----+----+----+

该表被分为多个 2x4 子组:



我想按照数字指示的顺序迭代这个一维输入 vector/数组。 (基本上每个 2x4 子组,一个接一个地进行)。
在循环内部,我想将当前处理的子组的 8 个元素加载到 vector/int 中以进行进一步处理。
所以最后我应该处理 6 个子组,第一个包含数字 1 到 8,第二个包含数字 9 到 16 等等。
应该从左到右处理组。

说明: 输入数据中的数字仅作为示例,以明确处理数据的顺序。输入数据可能包含完全随机的值。应保持每个组中值的顺序。组内不应该有排序/重新排序。重要的是子组/数组维度等的约束。

连同一维数组/vector ,我知道网格的维度和子组的大小:
int grid_width = 6; // Variable, but will always be a multiple of 2, to match subgroup width
int grid_height = 8;  // Variable, but will always be a multiple of 4, to match subgroup height
const int group_width = 2; // Constant, subgroup width is always 2.
const int group_height = 4; // Constant, subgroup height is always 4.

我的想法是有一个循环遍历整个数据,然后两个循环相应地处理子组。但是我真的很难让元素的循环条件和索引正确。我的思考过程是这样的:
// Iterate over entire data
for (int i = 0; i < grid_width * grid_height; i += (group_width * group_height))
{
    int block[8];
    // Iterate groups in correct order
    for (int j = 0; j < group_height; j++)
    {
        for (int k = 0; k < group_width; k++)
        {
            // Grab current element in group
            int value = input_array[i * grid_width + j]; // ?? This ain't right

            // Add element to group array/vector
            block[??] = ??;
        }
    }

    // Do further processing with the group array
}

有人可以帮我正确地循环吗?
我希望这个问题足够清楚。如果没有,请告诉我。

最佳答案

我想这将完成这项工作:

编辑:我添加了这个解释,因为到目前为止有些人无法理解这个解决方案,尽管它只包含一些简单的线性索引计算,并且因为我没有看到任何非 TL;DR 但完整的解决方案:
我们从前到后遍历输入数据。我们总是计算我们读取的值所属的索引。我们将值存储到适当的索引中。
组是二次块。我们使用 group_position_x 来存储我们在每个组中的水平位置。类似地,我们使用 group_position_y 表示组内的垂直位置,从左上角开始。
我们使用 col 来声明我们连续在 col th 组中。
类似地,我们使用 row 来声明我们在列中的第 row 组中。
然后我们可以轻松计算从输入读取的值必须存储的位置。
该组是所有的 col + [col-size] * row th 组。
以类似的方式,我们使用组内的 x 和 y 坐标来查看刚读取的值必须存储在组内的哪个索引处。
请注意,索引从 0 开始。另外,请参阅下面代码中的注释。colrow 和组内坐标的新值可以说是在每一步递增。当然,我们在每种情况下都讨论以某个整数为模的增量。在某些情况下,如果满足其他索引的某些溢出条件,则会发生“+1”。


using data_type = int // change type to correctly group data not being integers
using group = std::vector<data_type>; // reprensents the values of one group
const data_type DEFAULT{ -1 };

/**
@param data_begin begin iterator of the input data
@param data_end end iterator of the input data
@return a vector of all groups from top to bottom, from left to right.
*/
template<class _Const_Iterator>
std::vector<group> grouping(int grid_width, int grid_height, int group_width, int group_height, _Const_Iterator data_begin, _Const_Iterator data_end){
 const int GROUPS_PER_ROW{ grid_width / group_width };
 const int GROUPS_PER_COL{ grid_height / group_height };
 const int NUMBER_GROUPS{ GROUPS_PER_ROW * GROUPS_PER_COL };
 const int GROUP_SIZE{ group_width * group_height };
 std::vector<group> result(NUMBER_GROUPS, group(GROUP_SIZE, DEFAULT)); // create empty result vector with correct size.
 std::size_t group_index{ 0 }; // id of the current group
 std::size_t group_position_y{ 0 }; // currrent vertical position inside a group block
 std::size_t group_position_x{ 0 }; // current horizontal position inside a group block
 std::size_t row{ 0 }; // current row with respect to the groups
 std::size_t col{ 0 }; // current column with respect to the groups

 // iterate through all input data, copy data cell to target structur (result), calculate the correct indices for the next input data cell
 for (_Const_Iterator it{data_begin}; it != data_end; ++it){
  result[group_index][group_position_y + group_height * group_position_x] = *it;

  group_position_x = (group_position_x + 1) % group_width; // new horizontal position inside group
  auto old_col{ col };
  col = (col + (group_position_x == 0)) % GROUPS_PER_ROW; // new column with respect to the groups
  auto old_group_position_y{ group_position_y };
  group_position_y = (group_position_y  + (col == 0 && col != old_col)) % group_height; // new vertical position inside group
  row = (row + (group_position_y == 0 && group_position_y != old_group_position_y)) % GROUPS_PER_COL ; // new row with respect to the groups
  group_index = col + GROUPS_PER_ROW * row; 
 }
 return result;
}

在我个人看来,最好不要使用太多的嵌套循环,而是进行索引计算。

关于c++ - 按特定顺序迭代数组元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62127964/

相关文章:

c++ - Windows中打开文件的数量是否有限制

c - 反转数组,为什么除以2就可以了?

java - 如何在 java 中有效地处理数百万元组的集合?

c++ - 设计模式,对象的 vector ,每一种都有两种可能的类型

c++ - 在 C++ 中重新声明具有相同名称的 std::container() 是否会清除以前的数据?

c++ - 将项目添加到链接列表中,通过引用或值传递?

c++ - SDL_GL_SwapWindow 性能不佳

c++ - 为什么不能将 *pointer+offset 用作左值? ("error: non-lvalue in assignment")

python - 重新采样并调整 numpy 数组的大小

javascript - 道场数据网格 : Multiple values in a single field