Читаем Программирование полностью

  Cmp_by_name — это объект-функция, сравнивающий два объекта класса Record по членам name. Для того чтобы дать пользователю возможность задавать критерий сравнения, в стандартном алгоритме sort предусмотрен необязательный третий аргумент, указывающий критерий сортировки. Функция Cmp_by_name() создает объект Cmp_by_name для алгоритма sort(), чтобы использовать его для сравнения объектов класса Record. Это выглядит отлично, в том смысле, что нам не приходится об этом беспокоиться самим. Все, что мы должны сделать, — определить классы Cmp_by_name и Cmp_by_addr.

// разные сравнения объектов класса Record:

struct Cmp_by_name {

  bool operator()(const Record& a,const Record& b) const

    { return a.name < b.name; }

};

struct Cmp_by_addr {

  bool operator()(const Record& a, const Record& b) const

    { return strncmp(a.addr,b.addr,24) < 0; }  // !!!

};

Класс Cmp_by_name совершенно очевиден. Оператор вызова функции operator()() просто сравнивает строки name, используя оператор < из стандартного класса string. Однако сравнение в классе Cmp_by_addr выглядит ужасно. Это объясняется тем, что мы выбрали неудачное представление адреса — в виде массива, состоящего из 24 символов (и не завершающегося нулем). Мы сделали этот выбор частично для того, чтобы показать, как объект-функцию можно использовать для сокрытия некрасивого и уязвимого для ошибок кода, а частично для того, чтобы продемонстрировать, что библиотека STL может решать даже ужасные, но важные с практической точки зрения задачи. Функция сравнения использует стандартную функцию strncmp(), которая сравнивает массивы символов фиксированной длины и возвращает отрицательное число, если вторая строка лексикографически больше, чем первая. Как только вам потребуется выполнить такое устаревшее сравнение, вспомните об этой функции (см., например, раздел Б.10.3).

<p id="AutBody_Root397"><strong>21.5. Численные алгоритмы</strong></p>

Большинство стандартных алгоритмов из библиотеки STL связаны с обработкой данных: они их копируют, сортируют, выполняют поиск среди них и т.д. В то же время некоторые из них предназначены для вычислений. Они могут оказаться полезными как для решения конкретных задач, так и для демонстрации общих принципов реализации численных алгоритмов в библиотеке STL. Существуют всего четыре таких алгоритма.

Эти алгоритмы определены в заголовке . Мы опишем первые два из них, а остальные при необходимости читатели могут изучить самостоятельно.

<p id="AutBody_Root398"><strong>21.5.1. Алгоритм accumulate()</strong></p>

Простейшим и наиболее полезным численным алгоритмом является алгоритм accumulate(). В простейшем варианте он суммирует значения, принадлежащие последовательности.

template T accumulate(In first, In last, T init)

{

  while (first!=last) {

    init = init + *first;

    ++first;

  }

  return init;

}

Получив начальное значение init, он просто добавляет к нему каждое значение из последовательности [first:last] и возвращает сумму. Переменную init, в которой накапливается сумма, часто называют аккумулятором (accumulator). Рассмотрим пример.

int a[] = { 1, 2, 3, 4, 5 };

cout << accumulate(a, a+sizeof(a)/sizeof(int), 0);

Этот фрагмент кода выводит на экран число 15, т.е. 0+1+2+3+4+5 (0 является начальным значением). Очевидно, что алгоритм accumulate() можно использовать для всех видов последовательностей.

void f(vector& vd,int* p,int n)

{

  double sum = accumulate(vd.begin(),vd.end(),0.0);

  int sum2 = accumulate(p,p+n,0);

}

Тип результата (суммы) совпадает с типом переменной, которую алгоритм accumulate() использует в качестве аккумулятора. Это обеспечивает высокую степень гибкости которая может играть важную роль. Рассмотрим пример.

void f(int* p,int n)

{

  int s1 = accumulate(p, p+n, 0);        // суммируем целые числа в int

  long sl = accumulate(p, p+n, long(0)); // суммируем целые числа

                                         // в long

 double s2 = accumulate(p, p+n, 0.0);    // суммируем целые числа

                                         // в double

}

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