#c #iterator #set
#c #итератор #установить
Вопрос:
У меня есть функциональность, в которой я хочу сравнить каждый элемент набора с предыдущими элементами. Я хочу сделать что-то вроде этого:
std::set<int> sSet;
std::set<int>::iterator it;
std::set<int>::iterator itR;
sSet.insert(1);
sSet.insert(2);
sSet.insert(3);
sSet.insert(4);
sSet.insert(5);
sSet.insert(6);
for (it=sSet.begin(); it!=sSet.end(); it) //simple forward loop
{
itR = it;
if(it != sSet.begin())
itR--;
for(;itR!=sSet.begin();itR--)
{
//Reverse iteration
//for comparing every element to all the previous elements
//Problem here is it goes up to the second element only and not first
//because of the condition itR!=sSet.begin()
}
}
Я думал об использовании обратных итераторов здесь, но опять же я не смог найти способ установить обратный итератор из определенной позиции (или прямого итератора).
Есть ли какой-нибудь правильный способ сделать это?
Обновление: набор, используемый выше, предназначен только для демонстрации. Фактическая реализация как набор класса и определяется следующим образом:
std::set<TBigClass, TBigClassComparer> sSet;
class TBigClassComparer
{
public:
bool operator()(const TBigClass s1, const TBigClass s2) const
{
//comparison logic goes here
}
};
Ответ №1:
Хотите обратного ?! Используйте обратный итератор:
std::set<int> sSet;
std::set<int>::iterator it;
std::reverse_iterator<std::set<int>::iterator> itR;
sSet.insert(1);
sSet.insert(2);
sSet.insert(3);
sSet.insert(4);
sSet.insert(5);
sSet.insert(6);
for (it=sSet.begin(); it!=sSet.rend(); it) //simple forward loop
{
itR = std::reverse_iterator<std::set<int>::iterator>(it);
for(;itR!=sSet.rbegin(); itR)
{
//Reverse iteration
//for comparing every element to all the previous elements
//Problem here is it goes up to the second element only and not first
//because of the condition itR!=sSet.begin()
}
}
Обратите внимание, однако, что когда итератор отменяется, перевернутая версия указывает не на тот же элемент в диапазоне, а на предшествующий ему. Это сделано для того, чтобы упорядочить конечный элемент диапазона: итератор, указывающий на конечный элемент диапазона, при обратном изменении изменяется на указатель на последний элемент (не за ним) диапазона (это будет первыйэлемент диапазона, если наоборот). И если итератор для первого элемента в диапазоне отменяется, обратный итератор указывает на элемент перед первым элементом (это был бы конечный элемент диапазона, если перевернутый).
Комментарии:
1. itR = it; Это недопустимое присвоение
2. @skmic, да, спасибо. Я отредактировал ответ — я изменил способ использования reverse_iterator
3. Спасибо за объяснение. Где вы инициализировали itR? Я предполагаю, что вы хотели удалить эту строку ‘itR = it;’, поскольку это привело бы к ошибке компиляции. Таким образом, itR теперь является нулевым ptr.
4. @skmic Я исправил это с помощью оператора присваивания
5. @spineight Еще одно исправление, внутренний цикл for должен иметь условие itR != sSet.rend(), а не sSet.rbegin(), поскольку мы выполняем обратный переход, и это условие if(it != sSet.begin()) itR; больше не требуется. Ваше решение работает :).
Ответ №2:
Вы можете использовать внутренний цикл while:
while (true)
{
// do your comparison here
if (itR == sSet.begin())
break;
--itR;
}