如何使用1d索引迭代2d向量

时间:2020-08-07 12:33:19

标签: c++ algorithm pointers vector iterator

给出int向量的向量(例如),下面的代码允许我将平面位置映射到2d索引并访问元素:

int x = 0, y = 0, acc = 0;

while ((acc = myVector[x].size()+acc) <= position) {
     x++;
     y= acc;
}
y = position - y;

我想知道是否有一种方法可以使用单个指针对2d向量的所有元素进行迭代,从而将其增加位置编号。

EDIT1:

std::vector<std::vector<int>> myVector;

myVector.emplace_back();

for (int i = 0; i < 10; i++) {
    myVector[0].emplace_back(0);
}

myVector.emplace_back();
for (int i = 0; i < 5; i++) {
    myVector[0].emplace_back(1);
}

myVector.emplace_back();
for (int i = 0; i < 8; i++) {
    myVector[0].emplace_back(2);
}

for (auto row : myVector) {
    for (auto col : row) {
        std::cout << col << std::endl;
    }
}

我需要创建一个指向myVector[0][0]所指向的第一个元素的指针,然后在第一行的末尾与下一行的开始之间创建一个链接,这样我就可以使用单个指针。 如果我需要在位置12处放置元素,则只需增加指针就可以将元素放置在位置(1,1)。 基本上,我正在尝试使用std :: vectors

模拟c数组的行为。

3 个答案:

答案 0 :(得分:0)

在c ++ 20中,使用<ranges>标头直接支持此功能。所以你可以简单地做:

namespace srv = std::ranges::views;

for (auto i : myVector | srv::join)
     std::cout << i << std::endl;

这里是demo

使用range-v3,您可以像这样创建连接视图的vector

namespace rv = ranges::views;
    
auto j = myVector | rv::join | ranges::to<std::vector<int>>;

然后将其索引到任意位置。

这里是demo

答案 1 :(得分:0)

编写您自己的容器类,该容器类将执行以下操作:

  1. 将向量的向量作为构造函数参数。将向量地址的向量存储为其成员。
  2. 实现get(size_t p)进行迭代,如下所示:
size_t i;
for (i = 0; i < v.size() && p > v[i].size(); i++)
{
   p -= v[i].size();
}
return v[i][p];
  1. 重载[]指向要获取

答案 2 :(得分:0)

我想知道是否有一种方法可以使用单个指针对2d向量的所有元素进行迭代

,没有。您不能假设第一个向量的元素之后是第二个向量的元素,等等。

您可以改为使用std::vector<int>来连续存储所有元素,然后将std::vector<std::span<int>>构造为这些元素的“ 2d”视图

std::vector<int> raw;

for (int i = 0; i < 10; i++) {
    raw.emplace_back(0);
}

for (int i = 0; i < 5; i++) {
    raw.emplace_back(1);
}

for (int i = 0; i < 8; i++) {
    raw.emplace_back(2);
}

std::vector<std::span<int>> myVector;
myVector.emplace_back(raw.data(), 10);
myVector.emplace_back(raw.data() + 10, 5);
myVector.emplace_back(raw.data() + 15, 8);

for (auto row : myVector) {
    for (auto col : row) {
        std::cout << col << std::endl;
    }
}

See it live