Выбрать главу

// svecl содержит 10 элементов

// svec2 содержит 24 элемента

// после присваивания оба содержат по 24 элемента

svecl = svec2;

Контейнер-адресат (svec1) теперь содержит столько же элементов, сколько контейнер-источник (svec2). 10 элементов, изначально содержавшихся в svec1, удаляются (для каждого из них вызывается деструктор класса string).

Функция обмена swap() может рассматриваться как дополнение к операции присваивания. Когда мы пишем:

svecl.swap( svec2 );

svec1 после вызова функции содержит 24 элемента, которые он получил бы в результате присваивания:

svecl = svec2;

но зато теперь svec2 получает 10 элементов, ранее находившихся в svec1. Контейнеры “обмениваются” своим содержимым.

6.6.3. Обобщенные алгоритмы

Операции, описанные в предыдущих разделах, составляют набор, поддерживаемый непосредственно контейнерами vector и deque. Согласитесь, что это весьма небогатый интерфейс и ему явно не хватает базовых операций find(), sort(), merge() и т.д. Планировалось вынести общие для всех контейнеров операции в набор обобщенных алгоритмов, которые могут применяться ко всем контейнерным типам, а также к массивам встроенных типов. (Обобщенные алгоритмы описываются в главе 12 и в Приложении.) Эти алгоритмы связываются с определенным типом контейнера с помощью передачи им в качестве параметров пары соответствующих итераторов. Вот как выглядят вызовы алгоритма find() для списка, вектора и массива разных типов:

#include list

#include vector

int ia[ 6 ] = { 0, 1, 2, 3, 4, 5 };

vectorstring svec;

listdouble dtist;

// соответствующий заголовочный файл

#include algorithm

vectorstring::iterator viter;

listdouble::iterator liter;

#int *pia;

// find() возвращает итератор на найденный элемент

// для массива возвращается указатель ...

pia = find( ia[0], ia[6], some_int_value );

liter = find( dlist.begin(), dlist.end(), some_double_value );

viter = find( svec.begin(), svec.end(), some_string_value );

Контейнер list поддерживает дополнительные операции, такие, как sort() и merge(), поскольку в нем не реализован произвольный доступ к элементам. (Эти операции описаны в разделе 12.6.)

Теперь вернемся к нашей поисковой системе.

Упражнение 6.11

Напишите программу, в которой определены следующие объекты:

int ia[] = { 1, 5, 34 };

int ia2[] = { 1, 2, 3 };

int ia3[] = { 6, 13, 21, 29, 38, 55, 67, 89 };

vectorint ivec;

Используя различные операции вставки и подходящие значения ia, ia2 и ia3, модифицируйте вектор ivec так, чтобы он содержал последовательность:

{ 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 }

Упражнение 6.12

Напишите программу, определяющую данные объекты:

int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };

listint ilist( ia, ia+11 );

Используя функцию-член erase() с одним параметром, удалите из ilist все нечетные элементы.

6.7. Читаем текстовый файл

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

Как получить одну строку текста? Стандартная библиотека предоставляет для этого функцию getline():

istream

getline( istream is, string str, char delimiter );

getline()берет из входного потока все символы, включая пробелы, и помещает их в объект типа string, до тех пор пока не встретится символ delimiter, не будет достигнут конец файла или количество полученных символов не станет равным величине, возвращаемой функцией-членом max_size()класса string.

Мы будем помещать каждую такую строку в вектор.

Мы вынесли код, читающий файл, в функцию, названную retrieve_text(). В объекте типа pair дополнительно сохраняется размер и номер самой длинной строки. (Полный текст программы приводится в разделе 6.14.)

Вот реализация функции ввода файла:

// возвращаемое значение - указатель на строковый вектор

vectorstring,allocator*

retrieve_text()

{

string file_name;

cout "please enter file name: ";

cin file_name;

// откроем файл для ввода ...

ifstream 1nfile( file_name.c_str(), ios::in );

if ( ! infile ) {

cerr "oops! unable to open file "

file_name " -- bailing out!\n";

exit( -1 );

}

else cout '\n';

vectorstring, allocator *1ines_of_text =

new vectorstring, allocator;

string textime;

typedef pairstring::size_type, int stats;