Анимация
JavaScript
|
Главная Библионтека #include <algor1thm> using namespace std; int mainO 11st<int> colU: vector<int> C0112; Вставка элементов со значениями от 1 до 9 for Сint i=l: i<=9; ++1) { colli,push back(i); ОШИБКА ВРЕМЕНИ ВЫПОЛНЕНИЯ: - перезапись несуществующих элементов в приемнике сору (colli,beginC), colli.end(). Источник coll2.beginO): Приемник ... В приведенном примере вызывается алгоритм сору(), который просто копирует все элементы первого интервала во второй (приемный) интервал. Как обычно, для первого интервала определяются обе границы, а для второго - только нач;1Л0. Но данный алгоритм производит перезапись элементов вместо вставки, поэтому он требует, чтобы количество злементов п приемном интервале было достаточным для перезаписи. Если элементов пе хватит (как в приведенном примере), последствия будут непредсказуемыми. На практике это часто означает перезапись данных, находящихся в памяти после coll2.end(). Если повезет, произойдет сбой программы; по крайней мере, вы будете знать, что случилось что-то не то. Впрочем, вы можете упростить себе жизнь и воспользоваться безопасной версией STL, в которой неопределенное поведение автоматически приводит к выполнению некоторой процедуры обработки ошибок (см. с. 146). Чтобы избежать подобных ошибок, либо убедитесь, что приемный интервал имеет достаточные размеры, либо воспользуйтесь итераторами вшаош. Итераторы вставки рассматриваются на с. 116. Снач;1яа посмотрим, как изменить приемный интервал и обеспечить наличие в нем необходимого количества элементов. Чтобы приемный интервал был достаточно большим, необходимо либо создать его с нужным размером, либо изменить размер в программе. Оба варианта подходят только для последовательных контейнеров (векторов, деков и списков). Впрочем, это не создает особых проблем, поскольку ассоциативные контейнеры не могут использоваться в качестве приемника для алгоритмов с перезаписью (причины объясняются на с. 125). Пример увеличения размера контейнера приводится ниже. stl/copy2.cpp #include <iostream> #include <vector> #include <list> finclude <dGquG> linclude <algorithm> using namespace std: Int mainO { list<int> colli: vector<int> coll2: Вставка элементов со значениями от 1 до 9 for (int 1=1: 1<=9: ++1) { colli.push back(i): Изменение размера приемного интервапа. чтобы он были достаточен для работы алгоритма с перезаписью, С0112. resize (colli.sizeO): /* Копирование зпементов из первой коллекции во вторую * - перезапись существующих элементов в приемном интервале */ сору (colli.beginO . colli.endO. Источник coll2.beginO); Приемник /* Создание третьей коллекции с необходимым количеством элементов * - исходный размер передается в параметре */ deque<int> coll3(colll.sizeO); Копирование элементов из первой коллекции в третью сору (colli.beginO. colli.endO. Источник соИЗ.beginO): Приемник Размеры существующего контейнера со112 изменяются функцией resize(): C0112.resize (colli.sizeO): Коллекция соПЗ инициализируется с явным заданием начального размера, чтобы количество элементов в ней соответствовало количеству элементов в colli: deque<1nt> coll3(colll.size()); Как при изменении размеров, так и при инициализации с заданным размером создаются новые элементы. Эти элементы инициализируются конструктором по умолчанию, поскольку их создание происходит без передачи аргументов. Передача дополнительного аргумента конструктору и функции resize() позволяет инициализировать новые элементы. Итераторные адаптеры Итераторы являются чистыми абстракциямщ иначе говоря, любой объект, кото- \ рый ведет себя как итератор, является итератором. По этой причине вы можете ] написать класс, который обладает интерфейсом итератора, но делает нечто совершенно иное. Стандартная библиотека С++ содержит несколько готовых специализированных итераторов, называемых итераторными адаптерами. Не стоит полагать, что итераторные адаптеры являются обычными вспомогательными классами; они наделяют саму концепцию итераторов рядом новых возможностей. В следующих подразделах представлены три разновидности итераторных адаптеров: О итераторы вставки; О потоковые итераторы; О обратные итераторы. Дополнительная информация приводится на с. 270. Итераторы вставки Первая разновидность итераторных адаптеров - итераторы вставки - позволяет использовать алгоритмы в режиме вставки (вместо режима перезаписи). В частности, итераторы вставки решают проблему с нехваткой места в приемном интервале при записи: приемный интервал просто увеличивается до нужных размеров. Поведение итераторов вставки слегка переопределено. О Если присвоить значение элементу, ассоциированному с итератором, это значение вставляется в коллекцию, с которой связан данный итератор. Три разновидности итераторов вставки позволяют вставлять элементы в разных местах - в начале, в конце или в заданной позиции. О Операция перехода вперед не производит никаких действий. Рассмотрим следующий пример: stl/соруЗ.срр linclude <iostrea[n> finclude <vector> #include <list> #include <deque> linclude <set> linclude <algorith[n> using namespace std: Int mainC) { list<int> colli; Вставка элементов со значениями от 1 до 9 в первую коллекцию 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 [ 32 ] 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |