Есть вектор строк. Прохожу в цикле по каждой строке, и в каждой строке опять в цикле прохожу по каждому символу и ищу '0'. Надо вывести позицию этого символа. И назрел вопрос, а можно ли это сделать не используя дополнительный счетчик? То есть обойтись только итераторами. За ранее благодарю.
for(auto line = lines.begin(); line != lines.end(); ++line)
{
for(auto symbol = (*line).begin(); symbol != (*line).end(); ++symbol)
{
if (*symbol == '0')
{
cout << "Номер символа: " << /*номер символа*/ << endl;
}
}
}
В вашем конкретном случае нечего и огород городить: вычисление номера символа в строке (подразумевая std::string
) вы можете это сделать просто как symbol - line->begin()
.
Однако в общем, более абстрактном случае, если вы реализуете алгоритм, который по своей сути не требует произвольного доступа (random access) к используемой структуре данных, а обходится лишь последовательным доступом (sequential access), то более разумным решением, возможно, будет как-раз таки использовать именно счетчик. Таким образом вы по-прежнему сохраните последовательную структуру вашего алгоритма, т.е. решите задачу в рамках менее требовательного контракта последовательно доступа.
Используя вычитание итераторов вы искусственно привносите в чисто последовательный алгоритм существенно более сильное требование поддержки произвольного доступа. Не надо неоправданно накладывать на структуры данных чересчур ужесточенные требования. Если задача может быть решена эффективно в рамках идеи последовательного доступа - то лучше решить ее в рамках идеи последовательного доступа.
Например, если в чисто последовательном алгоритме вам завтра понадобится заменить вектор на список, то вам в реализации вашего алгоритма не придется делать никаких переделок. Но достаточно добавить в такой алгоритм вычитание итераторов - и все становится намного сложнее.
Будьте также осторожны с функциями типа std::distance
. Эта функция предназначена в первую очередь для вынужденного сокрытия неэффективностей, т.е. для того, чтобы тихо вычислять расстояние между итераторами даже тогда, когда итераторы не поддерживают эффективного вычисления расстояния. То есть std::distance
- это практически всегда костыль для очень узкоспециализированных ситуаций из разряда "тут невозможно обойтись без расстояния, даже если его вычисление неэффективно". Таких ситуаций надо старательно избегать.
Для этого имеется стандартная функция std::distance
, объявленная в заголовке <iterator>
.
Например,
cout << "Номер символа: " << std::distance( (*line).begin(), symbol ) << endl;
Для итераторов произвольного доступа, как в вашем случае, можно просто вычесть один итератор из другого
cout << "Номер символа: " << symbol - (*line).begin() << endl;
Но для вашего случая было бы проще использовать обычный цикл с индексом. Например,
for ( size_t i = 0; i != line->size(); ++i )
{
if ( ( *line )[i] == '0')
{
cout << "Номер символа: " << i << endl;
}
}
и использовать этот индекс в качестве значения позиции.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
DeviceIoControl с использованием управляющего кода FSCTL_GET_RETRIEVAL_POINTERS позволяет извлечь информацию о физическом расположении файла на дискеОднако,...
Доброго времени суток! Нужно создать очередь на основе массиваПоняла это буквально и написала так