Анимация
JavaScript
|
Главная Библионтека нием множества является значение типа pair (структура pair рассматривается на с. 50), то есть возвращаются два значения: О в поле second структуры pair возвращается признак успешного выполнения вставки; О в ноле first структуры pair возвращается позиция вставленного или существующего элемента. Во всех остальных случаях функции возвращают позицию нового элемента (или существующего элемента, если множество уже содержит элемент с таким значением). Ниже приведен пример использования этого интерфейса при вставке. В множество с вставляется новый элемент со значением 3.3: std::set<double> с; 1f (с.1nsert(3.3).second) { std;:cout « "3.3 inserted" « std::endl; else { std::cout « "3.3 already exists" « std::endl; Если программа должна дополнительно обработать новую или старую позицию элемента, программа усложняется: Определение переменной для возвращаемого значения insertO std::pair<std:;set<float>::iterator.bool> status: Вставка элемента с присваиванием возвращаемого значения status = c.insertCvalue); Обработка возвращаемого значения if (status.second) { std::cout « value « "inserted as element " else { std::cout « value « "already exists as element " std::cout « std: :d1stance(c.beginO.status.first) + 1 « std::endl; Результат вызова первых двух функций в этом фрагменте может выглядеть так: 8,9 inserted as element 4 7.7 already exists as element 3 Обратите внимание: тины возвращаемых значений для функций вставки с дополнительным параметром позиции не зависят от типа контейнера. Эти функции возвращают один итератор как для множеств, так и для мультимножеств. Тем не менее вызов этих функций приводит к таким же результатам, как и вызов функции без параметра позиции. Они отличаются только по скорости работы. Функции можно передать позицию итератора, но эта позиция воспринимается только как рекомендация для оптимизации быстродействия. Если элемент вставляется сразу же за позицией, переданной в первом архументе, сложность операции изменяется от логарифмической до амортизированной постоянной (сложность операций рассматривается на с. 37). Тот факт, что тип возвращаемого значения функций вставки с дополнительным параметром позиции не зависит от типа контейнера, как в случае функций вставки без параметра, гарантирует, что функция вставки обладает одинаковым и}[терфейсом для всех типов контейнеров. Этот интерфейс используется несколькими общими итераторами вставки (за подробностями обращайтесь на с. 279). Чтобы удалить элемент с некоторым значением, достаточно вызвать функцию erase(): std::set<Elem> coll: Удаление всех элементов с переданным значением coll.eraseCvalue); В отличие от списков функция удаления для множеств и мультимножеств называется erase(), а не remove() (см. описание функции remove() на с. 179). Она ведет себя иначе и возвращает количество удаленных элементов. Для множеств возвращаются только значения О и 1. Если мультимножество содержит дубликаты, вам не удастся использовать функцию eraseO для удаления только первого дубликата. Вместо этого можно воспользоваться следующим фрагментом: std::mult1set<Elem> coll; Удаление первого элемента с переданным значением std: ;muUlset<Elem>::iterator pos: pos = coll.find (elem); if (pos != coll .endO) { coll.erase(pos): Вместо алгоритма find() следует использовать функцию класса find(), потому что она работает быстрее (см. пример на с. 163). Обратите внимание: в данном случае также существуют различия в типе возвращаемого значения, а именно: для последовательных и ассоциативных контейнеров функция erase() возвращает разные типы. О Последовательные контейнеры поддерживают следующие функции erase(): iterator erase(iterator pos); iterator erase(iterator beg, iterator end); О Ассоциативные контейнеры поддерживают следующие функции erase(): void erase(iterator pos); void erasedterator beg. iterator end); Такие различия были внесены по соображениям быстродействия. В ассоциативных контейнерах на поиск и возвращение следующего элемента потребовалось бы дополнительное время, поскольку контейнер реализован в виде бинарного дерева. С другой стороны, чтобы программный код работал с любым контейнером, возвращаемое значение приходится игнорировать. Обработка исключений Множества и мультимножества относятся к категории узловых контейнеров, поэтому любая неудача при конструировании нового узла просто оставляет контейнер в прежнем состоянии. Более того, поскольку деструкторы обычно не генерируют исключений, удаление узла не может завершиться неудачей. Однако при вставке нескольких злементов из-за необходимости сохранения упорядоченности полное восстановление после исключений становится непрактичным. Поэтому для всех одноэлементных операций вставки обеспечивается транзакционная безопасность (то есть такие операции либо завершаются успешно, либо пе вносят изменений). Кроме того, все многоэлементные операции удаления всегда гарантированно завершаются успешно. Если в результате копирования/присваивания критерия сравнения возможны исключения, то функция swapO может их генерировать. На с. 148 приведены общие сведения об обработке исключений в STL, а на с. 254 перечислены все контейнерные операции, для которых предоставляются особые гарантии в отношении исключений. Примеры использования множеств и мультимножеств Следующая программа демонстрирует некоторые возможности м}1ожеств: cont/setl .срр #inclucle <iostream> #1nclucle <set> using namespace std: 1nt mainO { /* Тип коллекции: * - дубликаты запрещены * - элементы типа 1nt * - сортировка по убыванию */ typedef set<int,greater<1nt> > IntSet; IntSet colli; Пустое множество Определение distance() изменилось, поэтому в старых версиях STL приходится включать файл distance.hpp (см. с. 268). 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 |