Given a vector of vector of int (for example), the following piece of code allows me to map the flat position into a 2d index and access the element:
int x = 0, y = 0, acc = 0;
while ((acc = myVector[x].size()+acc) <= position) {
x++;
y= acc;
}
y = position - y;
I was wondering if there is a way to iterate over all the elements of my 2d vector using a single pointer thus incrementing it by the position number.
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;
}
}
What I need is to create a pointer to the first element pointed by myVector[0][0]
and then create a link between the end of the first row and the beginning of the next one so I can iterate over it using a single pointer. If I need the element at position 12 then just by incrementing the pointer I can get the element in position (1,1). Basically I'm trying to emulate the behaviour of the c arrays using std::vectors
In c++20, there is direct support for this functionality using the <ranges>
header. So you could simply do:
namespace srv = std::ranges::views;
for (auto i : myVector | srv::join)
std::cout << i << std::endl;
Here's a demo .
With range-v3, you can make a vector
of the joined view like this:
namespace rv = ranges::views;
auto j = myVector | rv::join | ranges::to<std::vector<int>>;
and then index into it arbitrary positions.
Here's a demo .
Write your own container class which does the following:
size_t i;
for (i = 0; i < v.size() && p > v[i].size(); i++)
{
p -= v[i].size();
}
return v[i][p];
I was wondering if there is a way to iterate over all the elements of my 2d vector using a single pointer
No , there isn't. You can't assume the elements of the first vector are followed by the elements of the second vector, etc.
You can instead use a std::vector<int>
to store all you elements contiguously, then construct a std::vector<std::span<int>>
as a "2d" view of those elements
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;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.