C ++ итерация контейнера назад N шагов - PullRequest
1 голос
/ 06 июня 2019

В C ++ я могу использовать reverse_iterator для зацикливания элементов контейнера, скажем, list, в обратном направлении.

Как перебрать определенное количество элементов?Не доходя до начала?Этот код работает, но я чувствую, что есть лучший способ.

std::list<int> mylist{1,2,3,4,5};
int cnt = 3;
for (auto rit = mylist.rbegin(); rit != mylist.rend(); ++rit) {
    if (cnt == 0) break;
    std::cout << *rit << " ";
    --cnt;
}

Ожидаемый результат {5, 4, 3}.

Ответы [ 3 ]

4 голосов
/ 06 июня 2019

Не доходит до начала?

Если вы можете это гарантировать, то

std::copy_n(mylist.rbegin(), 3, std::ostream_iterator<int>(std::cout, " "));

Или быть безопаснее

std::copy_n(mylist.rbegin(), std::min(mylist.size(), std::list<int>::size_type(3)), std::ostream_iterator<int>(std::cout, " "));

ЖИТЬ

4 голосов
/ 06 июня 2019

Вы можете настроить цикл следующим образом:

for (auto rit = mylist.rbegin(); rit != std::next(mylist.rbegin(), 3); ++rit)
{
   std::cout << *rit << " ";
}

, но учтите, что для его надежной работы необходимо проверить, что список имеет размер не менее 3, или настроить параметр на std::nextкак в const auto n = std::min<std::size_t>(3, mylist.size());.

С C ++ 20 вы должны быть в состоянии (очевидно, не проверено)

#include <ranges>

for (int n : mylist | std::ranges::reverse_view | std::ranges::take_view(3))
  std::cout << n << "\n";

Это делает проверку размера лишней, так как take_viewограничен размером диапазона (он выполняет эту проверку внутри).

2 голосов
/ 06 июня 2019

Я бы не стал увеличивать / уменьшать и проверять условие в теле цикла, а ставить его там, где вы больше всего этого ожидаете:

std::list<int> mylist{1,2,3,4,5};
int cnt = 3;
for (auto rit = mylist.rbegin(); rit != mylist.rend() && cnt > 0; ++rit,--cnt) {
    std::cout << *rit << " ";
}

Теперь вы можете, например, добавить continue в любом месте тела цикла, не нарушая цикл.

PS: на самом деле мне больше нравятся другие ответы, но я оставлю этот, так как это минимальные изменения, и imho, увеличивающего / проверяющего счетчик цикла внутри тела цикла, следует избегать, если это возможно (и здесь это возможно) ).

...