Задача: Вывести каждый k-элемент set, начиная с какого-то. Если начинать с начала, то всё хорошо:
#include <bits/stdc++.h>
using namespace std;
int main()
{
set <int> a;
for (int i = 1; i<=10; i++)
{
a.insert(i);
}
/**< Выводим все значения на нечётных позициях, начиная с первого элемента */
for (auto it = a.begin(); it != a.end(); advance(it, 2))
{
cout << *it << ' ';
}
cout<<endl;
}
Если сдвигаю вывод, то вывод зацикливается при некоторых позициях сдвига и размере сдвига.
ЭТО ПОВИСНЕТ:
#include <bits/stdc++.h>
using namespace std;
int main()
{
set <int> a;
for (int i = 1; i<=10; i++)
{
a.insert(i);
}
/**< Если нужно начинать не с первого то */
auto it = a.begin();
advance(it, 1);
for (it ; it != a.end(); advance(it, 2))
{
cout << *it << ' ';
}
}
Я так понимаю программа зацикливается из-за того, что итератор никогда не становится равным a.end(), у кого есть знания, как такое можно записать правильно?
Единственное, что смог придумать — завел переменную, в которой держал "текущий номер" элемента set.
#include <bits/stdc++.h>
using namespace std;
int main()
{
set <int> a;
for (int i = 1; i<=10; i++)
{
a.insert(i);
}
/**< Если нужно начинать не с первого, то */
auto it = a.begin();
advance(it, 1);
int i = 1;
for (it ; it != a.end(); advance(it, 2))
{
i +=2;
if (i>a.size())
{
break;
}
cout << *it << ' ';
}
}
Первое, что приходит в голову — написать свою функцию
my_advance
, третий аргумент которой — итератор, до которого нужно идти (то есть в данном случае —a.end()
). Получилось так:Почему тогда не просто:
Вообще есть много способов, один из которых я привёл, но я не исключаю существование других.
Конкретно Ваш код, видимо, нельзя использовать, если, например, нужно начинать с элемента, индекс которого больше или равен расстоянию между элементами, которые нужно выводить, например:
10, 12, 14, 16, ...
. UPD. Как написано ниже, с небольшим изменением можно.Суть в том что итерировать сет можно только последовательно, как делать фильтрацию не имеет значения. Как мне кажется в вашем коде слишком много абстракций. В моем случае начальный элемент можно добавить одним условием i>start или проитерировать первые start элементов отдельным циклом. Код без внешней функции читается проще и понятен сходу. Без необходимости разбираться что значит my_advance.
Да, тут Вы, наверно, правы. Но всё же мой код можно один раз написать, как шаблон, и дальше пользоваться. Хотя на асимптотику это действительно не влияет.
Я не думаю, что этот код отвечает на вопрос, попробуйте сами вывести каждый 3 начиная с 4. Но за ответ спасибо.
Если цель — решить задачу, чтобы решение надежно работало.