В нашей маленькой программе мы считываем слова, а затем упорядочиваем их. Пока все, что мы делаем, кажется очевидным, но почему мы записываем слова в “неправильные” ячейки, так что потом вынуждены их сортировать? Кроме того, что еще хуже, оказывается, что мы записываем слова и выводим их на печать столько раз, сколько они появляются в потоке ввода.
Последнюю проблему можно решить, используя алгоритм unique_copy()
вместо алгоритма copy()
. Функция unique_copy()
просто не копирует повторяющиеся идентичные значения. Например, при вызове обычной функции copy()
программы введет строку
the man bit the dog
и выведет на экран слова
bit
dog
man
the
the
Если же используем алгоритм unique_copy()
, то программа выведет следующие слова:
bit
dog
man
the
ostream_iterator
позволяет вам (при необходимости) указывать строку, которая может быть выведена после каждого значения.
ostream_iterator
// потока вывода
Очевидно, что переход на новую строку — это распространенный выбор для вывода, позволяющий людям легче разбираться в результатах, но, возможно, вы предпочли бы использовать пробелы? Мы могли бы написать следующий код:
ostream_iterator
// вывода
В этом случае результаты вывода выглядели бы так:
bit dog man the
21.7.3. Использование класса set для поддержания порядка
Существует еще более простой способ получить такой вывод: использовать контейнер set
, а не vector
.
int main()
{
string from, to;
cin >> from >> to; // имена исходного и целевого файлов
ifstream is(from.c_str()); // создаем поток ввода
ofstream os(to.c_str()); // создаем поток вывода
istream_iterator
// из потока
istream_iterator
ostream_iterator
// вывода в поток
set
// данными из потока ввода
copy(b.begin(),b.end(),oo); // копируем буфер в поток вывода
}
set
, дубликаты игнорируются. Более того, элементы контейнера set
хранятся в требуемом порядке. Если в вашем распоряжении есть правильные инструменты, то большинство задач можно решить без труда.
21.7.4. Алгоритм copy_if()
Алгоритм copy()
выполняет копирование без каких-либо условий. Алгоритм unique_copy()
отбрасывает повторяющиеся соседние элементы, имеющие одинаковые значения. Третий алгоритм копирует только элементы, для которых заданный предикат является истинным.
template
Out copy_if(In first,In last,Out res,Pred p)
// копирует элементы, удовлетворяющие предикату
{
while (first!=last) {
if (p(*first)) *res++ = *first;
++first;
}
return res;
}
Используя наш объект-функцию Larger_than
из раздела 21.4, можем найти все элементы последовательности, которые больше шести.
void f(const vector
// копируем все элементы, которые больше шести
{
vector
copy_if(v.begin(),v.end(),v2.begin(),Larger_than(6));
// ...
}
copy_if
. В таком случае просто воспользуйтесь определением, данным в этом разделе.
21.8. Сортировка и поиск
map
и set
, или выполняя сортировку. Наиболее распространенной и полезной операцией сортировки в библиотеке STL является функция sort()
, которую мы уже несколько раз использовали. По умолчанию функция sort()
в качестве критерия сортировки использует оператор <
, но мы можем задавать свои собственные критерии.