6.4. Как определить последовательный контейнер?
6.4. Как определить последовательный контейнер?
Для того чтобы определить объект контейнерного типа, необходимо сначала включить соответствующий заголовочный файл:
#include vector
#inclnde list
#include deque
#include map
#include set
Определение контейнера начинается именем его типа, за которым в угловых скобках следует тип данных его элементов . Например:
vector string svec;
list int ilist;
Переменная svec определяется как вектор, способный содержать элементы типа string, а ilist – как список с элементами типа int. Оба контейнера при таком определении пусты. Чтобы убедиться в этом, можно вызвать функцию-член empty():
if ( svec.empty() != true )
; // что-то не так
Простейший метод вставки элементов – использование функции-члена push_back(), которая добавляет элементы в конец контейнера. Например:
string text_word;
while ( cin text_word )
svec.push_back( text_word );
Здесь строки из стандартного ввода считываются в переменную text_word, и затем копия каждой строки добавляется в контейнер svec с помощью push_back().
Список имеет функцию-член push_front(), которая добавляет элемент в его начало. Пусть есть следующий массив:
int ia[ 4 ] = { 0, 1, 2, 3 };
Использование push_back()
for ( int ix=0; ix4; ++ix )
ilist.push_back( ia[ ix ] );
создаст последовательность 0, 1, 2, 3, а push_front()
for ( int ix=0; ix4; ++ix )
ilist.push_front( ia[ ix ] );
создаст последовательность 3, 2, 1, 0.
Мы можем при создании явно указать размер массива – как константным, так и неконстантным выражением:
#include list
#include vector
#include string
extern int get_word_count( string file_name );
const int list_size = 64;
list int ilist( list_size );
vector string svec(get_word_count(string("Chimera")));
Каждый элемент контейнера инициализируется значением по умолчанию, соответствующим типу данных. Для int это 0. Для строкового типа вызывается конструктор по умолчанию класса string.
Мы можем указать начальное значение всех элементов:
list int ilist( list_size, -1 );
vector string svec( 24, "pooh" );
Разрешается не только задавать начальный размер контейнера, но и впоследствии изменять его с помощью функции-члена resize(). Например:
svec.resize( 2 * svec.size() );
Размер svec в этом примере удваивается. Каждый новый элемент получает значение по умолчанию. Если мы хотим инициализировать его каким-то другим значением, то оно указывается вторым параметром функции-члена resize():
// каждый новый элемент получает значение "piglet"
svec.resize( 2 * svec.size(), "piglet" );
Кстати, какова наиболее вероятная емкость svec при определении, если его начальный размер равен 24? Правильно, 24! В общем случае минимальная емкость вектора равна его текущему размеру. При удвоении размера емкость, как правило, тоже удваивается
Мы можем инициализировать новый контейнер с помощью существующего. Например:
vector string svec2( svec );
list int ilist2( ilist ) ;
Каждый контейнер поддерживает полный набор операций сравнения: равенство, неравенство, меньше, больше, меньше или равно, больше или равно. Сопоставляются попарно все элементы контейнера. Если они равны и размеры контейнеров одинаковы, то эти контейнеры равны; в противном случае – не равны. Результат операций “больше” или “меньше” определяется сравнением первых двух неравных элементов. Вот что печатает программа, сравнивающая пять векторов:
ivecl: 1 3 5 7 9 12
ivec2: 0 1 1 2 3 5 8 13
ivec3: 1 3 9
ivec4: 1 3 5 7
ivec5: 2 4
// первый неравный элемент: 1, О
// ivecl больше чем ivec2
ivecl ivec2 //false
ivec2 ivecl //true
// первый неравный элемент: 5, 9
ivecl ivec3 //true
// все элементы равны, но ivec4 содержит меньше элементов
// следовательно, ivec4 меньше, чем ivecl
ivecl ivec4 //false
// первый неравный элемент: 1, 2
ivecl ivec5 //true
ivecl == ivecl //true
ivecl == ivec4 //false
ivecl != ivec4 //true
ivecl ivec2 //true
ivec3 ivecl //true
ivec5 ivec2 //true
Существуют три ограничения на тип элементов контейнера (практически это касается только пользовательских классов). Для должны быть определены:
* операция “равно”;
* операция “меньше” (все операции сравнения контейнеров, о которых говорилось выше, используют только эти две операции сравнения);
* значение по умолчанию (для класса это означает наличие конструктора по умолчанию).
Все предопределенные типы данных, включая указатели и классы из стандартной библиотеки С++ удовлетворяют этим требованиям.
Упражнение 6.5
Объясните, что делает данная программа:
#include string
#include vector
#include iostream
#int main()
{
vectorstring svec;
svec.reserve( 1024 );
string text_word;
while ( cin text_word )
svec.push_back( text_word );
svec.resize( svec.size()+svec.size()/2 );
// ...
}
Упражнение 6.6
Может ли емкость контейнера быть меньше его размера? Желательно ли, чтобы емкость была равна размеру: изначально или после вставки элемента? Почему?
Упражнение 6.7
Если программа из упражнения 6.5 прочитает 256 слов, то какова наиболее вероятная емкость контейнера после изменения размера? А если она считает 512 слов? 1000? 1048?
Упражнение 6.8
Какие из данных классов не могут храниться в векторе:
(a)
class cl1 {
public:
c11( int=0 );
bool operator==();
bool operator!=();
bool operator=();
bool operator();
// ...
};
(b)
class c12 {
public:
c12( int=0 );
bool operator!=();
bool operator=();
// ...
};
(с)
class c13 {
public:
int ival;
};
(d)
class c14 {
public:
c14( int, int=0 );
bool operator==();
bool operator!=();
// ...
}
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
30.4. Последовательный сервер TCP
30.4. Последовательный сервер TCP Последовательный сервер TCP полностью обрабатывает запрос каждого клиента, прежде чем перейти к следующему клиенту. Последовательные серверы редко используются, но один из них, простой сервер времени и даты, мы показали в листинге 1.5.Тем не
(1.12) Можно ли с одного взгляда на экран определить, что за ОС стоит, WinME или W2k?
(1.12) Можно ли с одного взгляда на экран определить, что за ОС стоит, WinME или W2k? Можно, если включен индикатор переключателя клавиатуры. В WinME (как и во всех W9x) на нём одна маленькая, одна большая буква (En, или Ru), в W2k (как и во всех NT) обе буквы большие (EN или
Как определить приоритеты
Как определить приоритеты Даже при неограниченных кадровых ресурсах невозможно реализовать все идеи сразу. Гораздо более разумным будет поэтапное внедрение технологических и маркетинговых решений с тестированием и оценкой промежуточных результатов. Вопрос только в
Определить стратегию
Определить стратегию Социальные сети – это часть Social Media Marketing (SMM). Если вы хотите продвигаться в социальных сетях и в интернет-маркетинге, обращаясь к какому-то агентству или самостоятельно, важно понять одну вещь. Социальные сети – это только часть маркетинга.Сначала мы
Последовательный резонанс
Последовательный резонанс В предыдущем примере значения L и C были выбраны такими, чтобы обеспечить резонанс на частоте f=1 кГц. Во многих схемах резонансная частота неизвестна, и ее необходимо определить при анализе схемы. Создайте в Capture схему, подобную приведенной на
76. По умолчанию используйте vector . В противном случае выбирайте контейнер, соответствующий задаче
76. По умолчанию используйте vector. В противном случае выбирайте контейнер, соответствующий задаче РезюмеОчень важно использовать "правильный контейнер". Если у вас есть весомые причины выбрать определенный тип контейнера, используйте тот контейнер, который наиболее
Признаки, по которым можно определить, что вас хотят обмануть
Признаки, по которым можно определить, что вас хотят обмануть Несмотря на то, что видов и способов интернет-мошенничества существует достаточно много (в чем вы могли убедиться, ознакомившись с предыдущими главами книги), многие злоумышленники действуют шаблонно, по
8.4. Автоматическое добавление новых экземпляров класса в контейнер
8.4. Автоматическое добавление новых экземпляров класса в контейнер ПроблемаТребуется хранить все экземпляры класса в едином контейнере, не требуя от пользователей класса выполнения каких-либо специальных операций.РешениеВключите в класс статический член, являющийся
2.4.5.2. Последовательный файл регистрации Falcon
2.4.5.2. Последовательный файл регистрации Falcon Falcon использует последовательный файл регистрации, чтобы сохранить некоторые типы информации до того, как данные окончательно сохранятся в базе данных. Файл регистрации используется, чтобы сохранить следующие типы
Последовательный поиск
Последовательный поиск Теперь, когда мы определились с функцией сравнения, можно перейти к рассмотрению алгоритмов поиска элемента в массивах и связных списках. Массивы Массивы представляют собой простейшую реализацию набора элементов, для которой можно использовать
Вставка элемента в отсортированный контейнер
Вставка элемента в отсортированный контейнер Если необходимо создать отсортированный массив или связный список, у нас существует выбор того или иного метода поддержания порядка элементов. Можно сначала вставлять элементы в контейнер, а затем их сортировать и
Определить роли и обязанности
Определить роли и обязанности Ясно определяйте роли и обязанности по обеспечению безопасности в вашей компании. Если ответственность по обеспечению безопасности пересекает границы между подразделениями (например, ложится одновременно на системных администраторов,