Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Липпман.doc
Скачиваний:
7
Добавлен:
14.08.2019
Размер:
7.54 Mб
Скачать

6.13.2. Поиск элемента

Две операции, позволяющие отыскать в наборе определенное значение, – это find() и count(). find() возвращает итератор, указывающий на найденный элемент, или значение, равное end(), если он отсутствует. count() возвращает 1 при наличии элемента и 0 в противном случае. Добавим проверку на существование в функцию build_word_map():

if ( exclusion_set.count( textword ))

continue;


// добавим отсутствующее слово

6.13.3. Навигация по множеству

Для проверки наших кодов реализуем небольшую функцию, выполняющую поиск по одному слову (поддержка языка запросов будет добавлена в главе 17). Если слово найдено, мы будем показывать каждую строку, в которой оно содержится. Слово может повторяться в строке, например:

tomorrow and tomorrow and tomorrow

однако такая строка будет представлена только один раз.

Одним из способов не учитывать повторное вхождение слова в строку является использование множества, как показано в следующем фрагменте кода:

// получим указатель на вектор позиций

loc ploc = (*text_map)[ query_text ];

// переберем все позиции

// вставим все номера строк в множество

set< short > occurrence_lines;

loc::iterator liter = ploc->begin(),

liter_end = ploc->end();

while ( liter != liter_end ) {

occurrence_lines.insert( occurrence_lines.end(),

(*liter).first );

++liter;


}

Контейнер set не допускает дублирования ключей. Поэтому можно гарантировать, что occurrence_lines не содержит повторений. Теперь нам достаточно перебрать данное множество, чтобы показать все номера строк, где встретилось данное слово:

register int size = occurrence_lines.size();

cout << "\n" << query_text

<< " встречается " << size

<< " раз(а):")

<< "\n\n";

set< short >::iterator it=occurrence_lines.begin();

for ( ; it != occurrence_lines.end(); ++it ) {

int line = -it;

cout << "\t( строка "

<< line + 1 << " ) "

<< (*text_file)[line] << endl;


}

(Полная реализация query_text() представлена в следующем разделе.)

Класс set поддерживает операции size(), empty() и erase() точно таким же образом, как и класс map, описанный выше. Кроме того, обобщенные алгоритмы предоставляют набор специфических функций для множеств, например set_union() (объединение) и set_difference() (разность). (Они использованы при реализации языка запросов в главе 17.)

Упражнение 6.23

Добавьте в программу множество слов, в которых заключающее 's' не подчиняется общим правилам и не должно удаляться. Примерами таких слов могут быть Pythagoras, Brahms и Burne_Jones. Включите в функцию suffix_s() из раздела 6.10 проверку этого набора.

Упражнение 6.24

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