Программирование >>  Инициализация объектов класса, структура 

1 ... 182 183 184 [ 185 ] 186 187 188 ... 395


bool operator()( const string & s1, const string & s2 ) С++ дл?1 наtИHгKSl:иXize() < s2.size(); }

typedef vector<string, allocator> textwords; void process vocab( vector<textwords, allocator> *pvec )

if ( ! pvec ) {

вывести предупредительное сообщение return;

vector< string, allocator > texts;

vector<textwords, allocator>::iterator iter; for ( iter = pvec->begin() ; iter != pvec->end(); ++iter ) copy( (*iter).begin(), (*iter).end(),

back inserter( texts ));

отсортировать вектор texts sort( texts.begin(), texts.end() );

теперь посмотрим, что получилось

for each( texts.begin(), texts.end(), PrintElem() );

cout << \n\n ; раздеть части выведенного текста

удалить дубликаты vector<string, alloc

allocator>::iterator it; unique( texts.begin(), texts.end() ); .erase( it, texts.end() );

it =

texts.erase посмотрим, что осталось

for each( texts.begin(), texts.end(), PrintElem() ); cout << \n\n ;

отсортировать элементы

stable sort сохраняет относительный порядок равных элементов stable sort( texts.begin(), texts.end(), LessThan() ); for each( texts.begin(), texts.end(), PrintElem() );

cout << \n\n ;

подсчитать число строк, дина котор больше 6

int cnt = 0;

устаревшая форма count - в стандарте используется другая count if( texts.begin(), texts.end(), GreaterThan(), cnt );

cout << Number of words greater than length six are << cnt << endl;

static string rw[] = { and , if , or , but , the };

vector<string,allocator> remove words( rw, rw+5 );

vector<string, allocator>::iterator it2 = remove words.begin();

for ( ; it2 != remove words.end(); ++it2 ) {

int cnt = 0;

устаревшая форма count - в стандарте используется другая count( texts.begin(), texts.end(), *it2, cnt );

cout << cnt << instances removed: << (*it2) << endl;

texts.erase(

remove(texts.begin(),texts.end(),*it2) ,

texts.end()

cout << \n\n ;

for each( texts.begin(), texts.end(), PrintElem() );



Упражнение 12.2

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

Упражнение 12.3

Более надежную оценку уровня трудности текста дает анализ структурной сложности предложений. Пусть каждой запятой присваивается 1 балл, каждому двоеточию или точке с занятой - 2 балла, а каждому тире - 3 балла. Модифицируйте программу из упражнения 12.2 так, чтобы она подсчитывала сложность каждого предложения. Воспользуйтесь алгоритмом count if() для нахождения каждого из знаков препинания в векторе предложений. Выведите предложения в порядке сложности.

12.3. Объекты-функции

Наша функция min() дает хороший пример как возможностей, так и ограничений

template <typename Type> const Type&

min( const Type *p, int size ) {

Type minval = p[ 0 ]; for ( int ix = 1; ix < size; ++ix ) if ( p[ ix ] < minval )

minval = p[ ix ]; return minval;

механизма шаблонов:

Достоинство этого механизма - возможность определить единственный шаблон min() , который конкретизируется для бесконечного множества типов. Ограничение же заключается в том, что даже при такой конкретизации min() будет работать не со всеми.

Это ограничение вызвано использованием оператора меньше : в некоторых случаях базовый тин его не поддерживает. Так, класс изображения Imiage может и не предоставлять реализации такого оператора, но мы об этом не знаем и пытаемся найти минимальный кадр анимации в данном массиве изображений. Однако попытка конкретизировать min() для такого массива приведет к ошибке компиляции:

error: invalid types applied to the < operator: Image < Imag (ошибка: оператор < применен к некорректнтм типам: Image < I:

< Image)



template < typename Type,

bool (*Comp)(const Type&, const Type&)>

const Type&

min( const Type *p, int size, Comp comp ) {

Type minval = p[ 0 ]; for ( int ix = 1; ix < size; ++ix ) if ( Comp( p[ ix ] < minval ))

minval = p[ ix ]; return minval;

аргумента и возвращающую значение типа bool:

Такое решение вместе с нашей первой реализацией на основе встроенного оператора меньше обеспечивает универсальную поддержку для любого типа, включая и класс Imiage, если только м1 придумаем подходящую семантику для сравнения двух изображений. Основной недостаток указателя на функцию связан с низкой эффективностью, так как косвенный вызов не дает воспользоваться преимуществами встроенных функций.

Альтернативная стратегия параметризации заключается в применении объекта-функции вместо указателя (примеры мы видели в предыдущем разделе). Объект-функция - это класс, перегружающий оператор вызова (operator() ). Такой оператор инкапсулирует семантику обычного вызова функции. Объект-функция, как правило, передается обобщенному алгоритму в качестве аргумента, хотя можно определять и независимые объект1-функции. Например, если бы был определен объект-функция Addlmiages, который принимает два изображения, объединяет их некоторым образом и возвращает новое изображение, то мы могли бы объявить его следующим образом:

Addlmages AI;

Чтобы объект-функция удовлетворял нашим требованиям, м1 применяем оператор

Image im1( foreground.tiff ), im2( background.tiff ); ...

вызывает Image AddImages::operator()(const Image1&, const Image2&);

вызова, предоставляя необходимые операнды в виде объектов класса Image:

Image new image = AI (im1, im2 );

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

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

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



1 ... 182 183 184 [ 185 ] 186 187 188 ... 395

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика