++cnt;
// новое самое длинное слово? сохраним его
if ( curLen max )
{
max = curLen;
largest = buf;
}
}
cout "Число прочитанных слов " cnt endl;
cout "Длина самого длинного слова " max endl;
cout "Самое длинное слово " largest endl;
}
Однако запятая и кавычка по-прежнему считаются частью слова. Напишем функцию для удаления этих символов из слова:
#include string
void filter_string( string &str )
{
// элементы, подлежащие фильтрации
string filt_elems( "\",?." );
string::size_type pos = 0;
while (( pos = str.find_first_of( filt_elems, pos ))
!= string::npos )
str.erase( pos, 1 );
}
Эта функция работает правильно, но множество символов, которые мы собираемся отбрасывать, "зашито" в код. Лучше дать пользователю возможность самому передать строку, содержащую такие символы. Если он согласен на множество по умолчанию, то может передать пустую строку.
#include string
void filter_string( string &str,
string filt_elems = string("\",."))
{
string::size_type pos = 0;
while (( pos = str.find_first_of( filt_elems, pos ))
!= string::npos )
str.erase( pos, 1 );
}
Более общая версия filter_string() принимает пару итераторов, обозначающих диапазон, где производится фильтрация:
template class InputIterator
void filter_string( InputIterator first, InputIterator last,
string filt_elems = string("\",."))
{
for ( ; first != last; first++ )
{
string::size_type pos = 0;
while (( pos = (*first).find_first_of( filt_elems, pos ))
!= string::npos )
(*first).erase( pos, 1 );
}
}
С использованием этой функции программа будет выглядеть так:
#include string
#include algorithm
#include iterator
#include vector
#include iostream
bool length_less( string s1, string s2 )
{ return s1.size() s2.size(); }
int main()
{
istream_iterator string input( cin ), eos;
vector string text;
// copy - это обобщенный алгоритм
copy( input, eos, back_inserter( text ));
string filt_elems( "\",.;:");
filter_string( text.begin(), text.end(), filt_elems );
int cnt = text.size();
// max_element - это обобщенный алгоритм
string *max = max_element( text.begin(), text.end(),
length_less );
int len = max-size();
cout "Число прочитанных слов "
cnt endl;
cout "Длина самого длинного слова "
len endl;
cout "Самое длинное слово "
*max endl;
}
Когда мы применили в алгоритме max_element() стандартный оператор "меньше", определенный в классе string, то были удивлены полученным результатом:
Число прочитанных слов 65
Длина самого длинного слова 4
Самое длинное слово wind
Очевидно, что wind – это не самое длинное слово. Оказывается, оператор "меньше" в классе string сравнивает строки не по длине, а в лексикографическом порядке. И в этом смысле wind – действительно максимальный элемент. Для того чтобы найти слово максимальной длины, мы должны заменить оператор "меньше" предикатом length_less(). Тогда результат будет таким:
Число прочитанных слов 65
Длина самого длинного слова 9
Самое длинное слово beautiful
Упражнение 20.2
Прочитайте из стандартного ввода последовательность данных таких типов: string, double, string, int, string. Каждый раз проверяйте, не было ли ошибки чтения.
Упражнение 20.3
Прочитайте из стандартного ввода заранее неизвестное число строк. Поместите их в список. Найдите самую длинную и самую короткую строку.
20.3. Дополнительные операторы ввода/вывода