Сортировка вектора

Таблица 7. Предикаты стандартной библиотеки

Функциональные объекты

0 1.1 1.1 2.2 3.3 4.4

Вторая форма алгоритма sort позволяет задать произвольный критерий упорядочения.

Для этого нужно передать через третий аргумент соответствующий предикат, то есть функцию или функциональный объект, возвращающие значение типа bool. Использование функции в качестве предиката было показано выше.

Использованию функциональных объектов посвящен следующий раздел.

Функциональным объектом называется объект некоторого класса,

для которого определена единственная операция вызова функции operator().

В стандартной библиотеке определены шаблоны функциональных объектов для операций сравнения, встроенных в язык C++. Они возвращают значение типа bool, то есть являются предикатами (табл. 7).

ОперацияЭквивалентный предикат (функциональный объект)

== equal_to

!= not_equal_to

> greater

< less

>= greater_equal

<= less_equal

Очевидно, что при подстановке в качестве аргумента алгоритма требуется инстанцирование этих шаблонов, например: equal_to<int>().

Вернемся к последней программе, где с помощью алгоритма sort был отсортирован вектор v1. Заменим вызов sort на следующий:

sort(v1.begin(), v1.endO, greater<double>());

В результате вектор будет отсортирован по убыванию значений его элементов.

Несколько сложней обстоит дело, когда сортировка выполняется для контейнера с объектами пользовательского класса. В этом случае программисту нужно самому позаботиться о наличии в классе предиката, задающего сортировку по умолчанию, а также (при необходимости) определить функциональные классы, объекты которых позволяют изменять настройку алгоритма sort.

В приведенной ниже программе показаны варианты вызова алгоритма sort для вектора men, содержащего объекты класса Man.

В классе Man определен предикат — операция operator<(), — благодаря которому сортировка по умолчанию будет происходить по возрастанию значений поля name.

Кроме этого, в программе определен функциональный класс Less Age, использование которого позволяет осуществить сортировку по возрастанию значений поля age.

class Man {

public:

Man (string _name, int _age):

name(_name), age(_age) { }

// предикат, задающий сортировку по умолчанию

bool operator< (const Man& m) const {

return name < m.name;

}

friend ostream& operator<< (ostream&, const Man&);

friend struct LessAge;

private:

string name;

int age;

};

ostream& operator<<(ostream& os, const Man& m) {

return os << endl << m.name << ",\t age: " << m.age;

}

// Функциональный класс для сравнения по возрасту

struct LessAge {

bool operator() (const Man& a, const Man& b) {

return a.age < b.age;

}

};

int main() {

Man ar [] = {

Man(“Mary Poppins", 36),

Man("Count Basie", 70),

Man{“Duke Ellington", 90).

Man("Joy Amore", 18)

};

int size = sizeof(ar) / sizeof(Man);

vector<Man> men(ar, ar + size);

/ / Сортировка по имени (по умолчанию)

sort(men.begin(), men.end());

print(men);

// Сортировка по возрасту

sort(men.begin(), men.end(), LessAge());

print(men);

return 0;

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: