Зацикливание около начала с использованием итераторов std::vector

#c #vector #iterator #stdvector

Вопрос:

У меня есть итератор, который должен зацикливаться вблизи начала вектора всякий раз, когда он достигает своего конца, на сумму, которую он преодолел в конце, вот так:

 std::vector<int> vec = {...}, vec1;
std::vector<int>::iterator it = vec.begin();

for(;vec.size() != 0;){

it  = k; //k is a const integer
if(it >= vec.end()){
it -= items.end(); // something like that, but this syntax is obviously invalid
}

vec1.push_back(*it);
it = vec.erase(it);
}
 

Так что, возможно, я увеличу vec{1,2,3,4,5} на 3 , сначала он должен удалить 3, затем 1 и вставить их vec1 , в некотором смысле он зацикливается на том, что осталось, когда он достиг конца. Я перепробовал кучу разных синтаксисов, но всегда возникает ошибка несоответствия типов. Есть ли элегантный способ сделать это?

Комментарии:

1. it = items.begin(); ? Но вам нужно позаботиться о erase признании недействительным it

2. Всякий раз , когда вы используете erase , вы всегда должны использовать то, что он возвращает .

3. подождите… «за ту сумму, которую он перевалил за конец» ? Итератор не может пройти через конец контейнера. Вам лучше объяснить, какова фактическая цель вашего кода, потому что ваш текущий подход ошибочен

4. Вместо it = k; «возможно»: it = std::next(vec.begin(), (std::distance(vec.begin(), it) k) % vec.size()); сработало бы.

5. @463035818_is_not_a_number Я имел в виду, что он должен был начаться с самого начала сколько осталось до того, как он «пересек» бы конец. Если он увеличивается на 3 и находится в элементе n — 2, он должен перейти к первому элементу. Если он находится в элементе n — 1, он должен перейти ко второму элементу вектора (n-размер вектора). Есть ли в этом больше смысла?

Ответ №1:

XY-решение: Я рекомендую сохранить индекс вместо итератора и использовать оператор остатка.

 for(std::size_t i = 0; vec.size() != 0;){
    i = (i   k) % vec.size();
    vec1.push_back(vec[i]);
    vec.erase(vec.begin()   i);
}
 

Поэтому, возможно, я увеличу vec{1,2,3,4,5} на 3, сначала он должен удалить 3

Это не соответствует вашему попытанному коду. Если вы увеличите итератор до первого элемента на 3 и удалите его, то вы удалите элемент со значением 4.

Комментарии:

1. Это отлично работает после некоторых переделок, k действительно должен быть k — 1, в противном случае, если k = 3, он пропускает 3 элемента и вынимает 4-й вместо пропуска 2 и вынимания третьего, но это почти придирчиво. Большое спасибо!

2. @yomag1234 да, я не совсем был уверен, какой именно заказ был правильным для вас. Приспосабливайтесь по своему вкусу.