2.8. Стандартный массив - это вектор
2.8. Стандартный массив - это вектор
Хотя встроенный массив формально и обеспечивает механизм контейнера, он, как мы видели выше, не поддерживает семантику абстракции контейнера. До принятия стандарта C++ для программирования на таком уровне мы должны были либо приобрести нужный класс, либо реализовать его самостоятельно. Теперь же класс массива является частью стандартной библиотеки C++. Только называется он не массив, а вектор.
Разумеется, вектор реализован в виде шаблона класса. Так, мы можем написать
vectorint ivec(10);
vectorstring svec(10);
Есть два существенных отличия нашей реализации шаблона класса Array от реализации шаблона класса vector. Первое отличие состоит в том, что вектор поддерживает как присваивание значений существующим элементам, так и вставку дополнительных элементов, то есть динамически растет во время выполнения, если программист решил воспользоваться этой его возможностью. Второе отличие более радикально и отражает существенное изменение парадигмы проектирования. Вместо того чтобы поддержать большой набор операций-членов, применимых к вектору, таких, как sort(), min(), max(), find()и так далее, класс vector предоставляет минимальный набор: операции сравнения на равенство и на меньше, size() и empty(). Более общие операции, перечисленные выше, определены как независимые обобщенные алгоритмы.
Для использования класса vector мы должны включить соответствующий заголовочный файл.
#include vector
// разные способы создания объектов типа vector
vectorint vec0; // пустой вектор
const int size = 8;
const int value = 1024;
// вектор размером 8
// каждый элемент инициализируется 0
vectorint vec1(size);
// вектор размером 8
// каждый элемент инициализируется числом 1024
vectorint vec2(size,value);
// вектор размером 4
// инициализируется числами из массива ia
int ia[4] = { 0, 1, 1, 2 };
vectorint vec3(ia,ia+4);
// vec4 - копия vec2
vectorint vec4(vec2);
Так же, как наш класс Array, класс vector поддерживает операцию доступа по индексу. Вот пример перебора всех элементов вектора:
#include vector
extern int getSize();
void mumble()
{
int size = getSize();
vectorint vec(size);
for (int ix=0; ixsize; ++ix)
vec[ix] = ix;
// ...
}
Для такого перебора можно также использовать итераторную пару. Итератор – это объект класса, поддерживающего абстракцию указательного типа. В шаблоне класса vector определены две функции-члена – begin() и end(), устанавливающие итератор соответственно на первый элемент вектора и на элемент, который следует за последним. Вместе эти две функции задают диапазон элементов вектора. Используя итератор, предыдущий пример можно переписать таким образом:
#include vector
extern int getSize();
void mumble()
{
int size = getSize();
vectorint vec(size);
vectorint::iterator iter = vec.begin();
for (int ix=0; iter!=vec.end(); ++iter, ++ix)
*iter = ix;
// ...
}
Определение переменной iter
vectorint::iterator iter = vec.begin();
инициализирует ее адресом первого элемента вектора vec. iterator определен с помощью typedef в шаблоне класса vector, содержащего элементы типа int. Операция инкремента
++iter
перемещает итератор на следующий элемент вектора. Чтобы получить сам элемент, нужно применить операцию разыменования:
*iter
В стандартной библиотеке С++ имеется поразительно много функций, работающих с классом vector, но определенных не как функции-члены класса, а как набор обобщенных алгоритмов. Вот их неполный перечень:
алгоритмы поиска: find(), find_if(), search(), binary_search(), count(), count_if();
алгоритмы сортировки и упорядочения: sort(), partial_sort(), merge(), partition(), rotate(), reverse(), random_shuffle();
алгоритмы удаления: unique(), remove();
численные алгоритмы: accumulate(), partial_sum(), inner_product(), adjacent_difference();
алгоритмы генерации и изменения последовательности: generate(), fill(), transform(), copy(), for_each();
алгоритмы сравнения: equal(), min(), max().
В число параметров этих обобщенных алгоритмов входит итераторная пара, задающая диапазон элементов вектора, к которым применяется алгоритм. Скажем, чтобы упорядочить все элементы некоторого вектора ivec, достаточно написать следующее:
sort ( ivec.begin(), ivec.end() );
Чтобы применить алгоритм sort() только к первой половине вектора, мы напишем:
sort ( ivec.begin(), ivec.begin() + ivec.size()/2 );
Роль итераторной пары может играть и пара указателей на элементы встроенного массива. Пусть, например, нам дан массив:
int ia[7] = { 10, 7, 9, 5, 3, 7, 1 };
Упорядочить весь массив можно вызовом алгоритма sort():
sort ( ia, ia+7 );
Так можно упорядочить первые четыре элемента:
sort ( ia, ia+4 );
Для использования алгоритмов в программу необходимо включить заголовочный файл
#include algorithm
Ниже приведен пример программы, использующей разнообразные алгоритмы в применении к объекту типа vector:
#include vector
#include algorithm
#include iostream
int ia[ 10 ] = {
51, 23, 7, 88, 41, 98, 12, 103, 37, 6
};
int main()
{
vector int vec( ia, ia+10 );
vectorint::iterator it = vec.begin(), end_it = vec.end();
cout "Начальный массив: ";
for ( ; it != end_it; ++ it ) cout *it ;
cout " ";
// сортировка массива
sort( vec.begin(), vec.end() );
cout "упорядоченный массив: ";
it = vec.begin(); end_it = vec.end();
for ( ; it != end_it; ++ it ) cout *it ;
cout " ";
int search_value;
cout "Введите значение для поиска: ";
cin search_value;
// поиск элемента
vectorint::iterator found;
found = find( vec.begin(), vec.end(), search_value );
if ( found != vec.end() )
cout "значение найдено! ";
else cout "значение найдено! ";
// инвертирование массива
reverse( vec.begin(), vec.end() );
cout "инвертированный массив: ";
it = vec.begin(); end_it = vec.end();
for ( ; it != end_it; ++ it ) cout *it ;
cout endl;
}
Стандартная библиотека С++ поддерживает и ассоциативные массивы. Ассоциативный массив – это массив, элементы которого можно индексировать не только целыми числами, но и значениями любого типа. В терминологии стандартной библиотеки ассоциативный массив называется отображением (map). Например, телефонный справочник может быть представлен в виде ассоциативного массива, где индексами служат фамилии абонентов, а значениями элементов – телефонные номера:
#include map
#include string
#include "TelephoneNumber.h"
mapstring, telephoneNum telephone_directory;
(Классы векторов, отображений и других контейнеров в подробностях описываются в главе 6. Мы попробуем реализовать систему текстового поиска, используя эти классы. В главе 12 рассмотрены обобщенные алгоритмы, а в Приложении приводятся примеры их использования.)
В данной главе были очень бегло рассмотрены основные аспекты программирования на С++, основы объектно-ориентированного подхода применительно к данному языку и использование стандартной библиотеки. В последующих главах мы разберем эти вопросы более подробно и систематично.
Упражнение 2.22
Поясните результаты каждого из следующих определений вектора:
string pals[] = {
"pooh", "tiger", "piglet", "eeyore", "kanga" };
(a) vectorstring svec1(pals,pals+5);
(b) vectorint ivec1(10);
(c) vectorint ivec2(10,10);
(d) vectorstring svec2(svec1);
(e) vectordouble dvec;
Упражнение 2.23
Напишите две реализации функции min(), объявление которой приведено ниже. Функция должна возвращать минимальный элемент массива. Используйте цикл for и перебор элементов с помощью
индекса
template class elemType
итератора
elemType min (const vectorelemType vec);
2013-11-14 09:35:20 Safronik
Есть места где вы не объясняете код. Просто вставляете непонятную инструкцию или строчку. Сложно.
2012-06-27 18:30:04 FeelUs
"Упражнение 2.8 Отношение наследования между типом и подтипом служит примером отношения является." - как-то не по русски
2012-05-30 18:46:11
"... private: static const int DefaultArraySize = 12; " - на это билдер ругался до тех пор, пока я не поместил обьявление класса в .h ----------------------------- Не " else ix[ix] = array[ix]; " , а "...iа[ix]". ----------------------------- " int IntArray::operator[] (int index) " ругается на непричасность к классу IntArray ----------------------------- Словил ошибку линкёра после переноса реализации класса в IntArray.cpp (в IntArray.h есть его обьявление, директивы include тоже, эта пара - один unit.
2011-10-14 19:42:59 Crazy_penguin
Глава 2 - Рассматривается ООП, конструкторы и деструкторы. Глава 3 - Изучаем, что такое переменные и цикл for. Кто-то кого-то где-то ...
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
5.4. Стандартный ввод/вывод
5.4. Стандартный ввод/вывод 5.4.1. Потоки ввода-вывода Когда программа запускается на выполнение, в ее распоряжение предоставляются три потока (или канала): • стандартный ввод (standard input или stdin). По этому каналу данные передаются программе; • стандартный вывод (standard output или
14.1.4. Стандартный ввод и вывод
14.1.4. Стандартный ввод и вывод В главе 10 мы видели, как работают методы IO.popen и IO.pipe, но существует еще небольшая библиотека, которая иногда бывает удобна.В библиотеке Open3.rb есть метод popen3, который возвращает массив из трех объектов IO. Они соответствуют стандартному вводу,
Вектор (Vector)
Вектор (Vector) vector - вид последовательности, которая поддерживает итераторы произвольного доступа. Кроме того, он поддерживает операции вставки и удаления в конце с постоянным (амортизированным) временем; вставка и удаление в середине занимают линейное время. Управление
2.1.4. Стандартный ввод-вывод
2.1.4. Стандартный ввод-вывод В стандартной библиотеке языка С определены готовые потоки ввода и вывода (stdin и stdout соответственно). Они используются функциями scanf(), printf() и целым рядом других библиотечных функций. Согласно идеологии UNIX, стандартные потоки можно
6.2. Вектор или список?
6.2. Вектор или список? Первая задача, которую должна решить наша программа, – это считывание из файла заранее неизвестного количества слов. Слова хранятся в объектах типа string. Возникает вопрос: в каком контейнере мы будем хранить слова – в последовательном или
6.3. Как растет вектор?
6.3. Как растет вектор? Вектор может расти динамически. Как это происходит? Он должен выделить область памяти, достаточную для хранения всех элементов, скопировать в эту область все старые элементы и освободить ту память, в которой они содержались раньше. Если при этом
14.4.2. Вектор объектов
14.4.2. Вектор объектов Когда определяется вектор из пяти объектов класса, например:vector Point vec( 5 );* то инициализация элементов производится в следующем порядке5: С помощью конструктора по умолчанию создается временный объект типа класса, хранящегося в векторе.* К каждому
21.5.1. Команда ftp — стандартный FTP-клиент
21.5.1. Команда ftp — стандартный FTP-клиент Для открытия соединения с любым FTP-сервером введите команду: ftp <имя или адрес FTP-сервера> Можно просто ввести команду ftp, а в ответ на приглашение ftp> ввести команду: open <имя или адрес FTP-сервера> Лично мне больше нравится первый
5.6.1. Стандартный поток ввода
5.6.1. Стандартный поток ввода Файл стандартного потока ввода (stdin) имеет дескриптор 0. Из этого файла процессы извлекают свои входные данные. По умолчанию входной поток ассоциирован с клавиатурой (устройство /dev/tty), но чаще всего он поступает по каналу от других процессов или
5.6.2. Стандартный поток вывода
5.6.2. Стандартный поток вывода Файл стандартного потока вывода (stdout) имеет дескриптор 1. В этот файл записываются все выходные данные процесса. По умолчанию данные выводятся на экран терминала (устройство /dev/tty), но их можно также перенаправить в файл или послать по каналу
5.6.3. Стандартный поток ошибок
5.6.3. Стандартный поток ошибок Файл стандартного потока ошибок (stderr) имеет дескриптор 2. В этот файл записываются сообщения об ошибках, возникающих в ходе выполнения команды. По умолчанию сообщения об ошибках выводятся на экран терминала (устройство /dev/tty), но их также можно
КОСМОС: Красный вектор: Что нового мы узнали о Марсе за последние десят лет?
КОСМОС: Красный вектор: Что нового мы узнали о Марсе за последние десят лет? Автор: Александр БумагинС тех пор как переводчики переврали смысл работы Скиапарелли, разместив на Марсе рукотворные каналы, разговоры об этой планете не утихают. Голубая мечта о братьях по
7 февраля 2014 года — день истины, определивший вектор самосовершенствования Сергей Голубицкий
7 февраля 2014 года — день истины, определивший вектор самосовершенствования Сергей Голубицкий Опубликовано 07 февраля 2014 На сегодня у меня была запланирована бомба, потенциал которой я попытался вложить в название — «Окончательный вердикт по
USB – стандартный интерфейс
USB – стандартный интерфейс В большинстве камер предусмотрена возможность загрузки изображений в компьютер посредством кабеля. Сегодня большинство камер разрабатывается так, чтобы передавать снимки по шине USB (Universal Serial Bus – универсальная последовательная шина), и