|
Программирование >> Инициализация объектов класса, структура
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 ); У объекта-функции есть два преимущества по сравнению с указателем на функцию. Во-первых, если перегруженный оператор вызова - это встроенная функция, то компилятор может выполнить ее подстановку, обеспечивая значительный выигрыш в производительности. Во-вторых, объект-функция способен содержать произвольное Возможна и другая ситуация: оператор меньше существует, но имеет неподходящую семантику. Например, если мы хотим найти наименьшую строку, но при этом принимать во внимание только буквы, не учитывая регистр, то такой реализованный в классе оператор не даст нужного результата. Традиционное решение состоит в том, чтобы параметризовать оператор сравнения. В данном случае это можно сделать, объявив указатель на функцию, принимающую два
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |