Как перебрать 2d-вектор с помощью 1d-индекса - PullRequest
1 голос
/ 07 августа 2020

Учитывая вектор вектора типа int (например), следующий фрагмент кода позволяет мне сопоставить плоскую позицию с 2-мерным индексом и получить доступ к элементу:

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

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

Мне было интересно, есть ли там - это способ перебора всех элементов моего 2-мерного вектора с использованием одного указателя, увеличивая его на номер позиции.

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). В основном я пытаюсь имитировать поведение массивов c, используя std :: vectors

Ответы [ 3 ]

0 голосов
/ 07 августа 2020

Напишите свой собственный класс-контейнер, который выполняет следующие действия:

  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];
overload [], чтобы указать, чтобы получить
0 голосов
/ 07 августа 2020

Мне было интересно, есть ли способ перебрать все элементы моего 2-мерного вектора с помощью одного указателя

Нет , нет. Вы не можете предполагать, что за элементами первого вектора следуют элементы второго вектора, et c.

Вместо этого вы можете использовать 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;
    }
}

Посмотреть вживую

0 голосов
/ 07 августа 2020

В c ++ 20 эта функция напрямую поддерживается с помощью заголовка <ranges>. Итак, вы можете просто сделать:

namespace srv = std::ranges::views;

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

Вот демонстрация .

С range-v3 вы можете сделать vector объединенного представления следующим образом:

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

, а затем проиндексируйте в него произвольные позиции.

Вот демонстрация .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...