Читаем Программирование. Принципы и практика использования C++ Исправленное издание полностью

Последнюю проблему можно решить, используя алгоритм 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 oo(os,"\n"); // создает итератор для

                                      // потока вывода


Очевидно, что переход на новую строку — это распространенный выбор для вывода, позволяющий людям легче разбираться в результатах, но, возможно, вы предпочли бы использовать пробелы? Мы могли бы написать следующий код:


ostream_iterator oo(os," ");  // создает итератор для потока

                                      // вывода


В этом случае результаты вывода выглядели бы так:


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 ii(is);     // создаем итератор ввода

                                       // из потока

  istream_iterator eos;        // сигнальная метка для ввода

  ostream_iterator oo(os," "); // создаем итератор

                                       // вывода в поток

  set b(ii,eos);      // b — вектор, который инициализируется

                              // данными из потока ввода

  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& v)

  // копируем все элементы, которые больше шести

{

  vector v2(v.size);

  copy_if(v.begin,v.end,v2.begin,Larger_than(6));

  // ...

}


  Из-за моей ошибки этот алгоритм выпал из стандарта 1998 ISO Standard. В настоящее время эта ошибка исправлена, но до сих пор встречаются реализации языка С++, в которых нет алгоритма copy_if. В таком случае просто воспользуйтесь определением, данным в этом разделе.

21.8. Сортировка и поиск

  Часто мы хотим упорядочить данные. Мы можем добиться этого, используя структуры, поддерживающие порядок, такие как map и set, или выполняя сортировку. Наиболее распространенной и полезной операцией сортировки в библиотеке STL является функция sort, которую мы уже несколько раз использовали. По умолчанию функция sort в качестве критерия сортировки использует оператор <, но мы можем задавать свои собственные критерии.


template void sort(Ran first, Ran last);

template void sort(Ran first,Ran last,Cmp cmp);


В качестве примера сортировки, основанной на критерии, определенном пользователем, покажем, как упорядочить строки без учета регистра.


struct No_case { // lowercase(x) < lowercase(y)

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже