Анимация
JavaScript
|
Главная Библионтека Термин «устоичиность» означает tохранение (.оеюяпия ыеж/iy з.тускамн npoipaviMbi Также встреча-е1ся iep,\HHi «нерманентност1»> - Примеч перев 11.14. Устойчивые структуры данных Проблема Существует сложная структура данных, которую требуется сделать устойчивой (persistent). Решение Воспользуйтесь модулем MLDBM и либо DB File (предпочтительно), либо GDBM File; use MLDBM qw(DB Flle), use Fcntl, tie(%hash MLDBM , testfile db , 0 CREAT0 RDWR 0666) or die can t open tie to testfile db $ , tt Операции с %hash untie %hash. Комментарий Конечно, построение хэша из 100000 элементов займет немало времени. Сохранение его на диске (вручную или с помощью Storable) также потребует немалых расходов памяти и вычислительных ресурсов. Модули DBM решают эту проблему посредством связывания хзшей с файлами баз данных иа диске. Вместо того чтобы читать всю структуру сразу, они извлекают да1И1ые Л1ииь при необходимости. Для пользователя все выглядит так, словно состояние хэша сохраняется между вызовами программы К сожалению, значения устойчивого хэша должны представлять собой простые строки. Вам пе удастся легко использовать базу данных для хранения хэша хэшей, хэша массивов и т. д. - только хэши строк. Однако модуль MLDBM с CPAN позволяет сохранять ссылки в базе данных. Преобразование ссылок в строки для внешнего хранения осуществляется с помощью Data:; Dumper: use MLDBM qw(DB Flle) use Fcntl, tie(%hash MLDBM testfile db , 0 CREAT0 RDWR, 0666) or die can t open tie to testfile db $ , Теперь %hash может использоваться для выборки или сохранения сложных записей на диске. Единственный недостаток заключается в том, что к ссылкам нельзя обращаться напрямую. Приходится извлекать ссылку из базы, работать с ней, а затем снова сохранять в базе. # Не будет работать $hash{ some key }[4] = fred , # ПРАВИЛЬНО Saref = $hash{"some key"}; $aref->[4] = "fred"; $hash{"soiiie key") = $aref; > Смотри также- Документация но модулю MLDBM с CPAN; рецепты 14.1; 14.7; 14.11. 11.15. Программа: бинарные деревья Встроенные тины данных Perl представляют собой мощные, динамические структуры. В больщинстве программ этих стандартных возможностей оказывается вполне достаточно. Для выполнения простого поиска почти всегда следует использовать простые хэши. Как выразился Ларри, «Весь фокус в том, чтобы использовать сильные, а не слабые стороны Рег1». Однако хэши не обладают внутренним упорядочиванием элементов. Чтобы перебрать элементы хэша в определенном порядке, необходимо сначала извлечь ключи, а затем отсортировать их. При многократном выполнении это может отразиться на быстродействии программы, что, однако, вряд ли оправдывает затраты времени на разработку хитроумного алгоритма. Древовидные структуры обеспечивают упорядоченный перебор. Как реализовать дерево на Perl? Для начала загляните в свой любимый учебник но структурам данных. Воспользуйтесь анонимным хэшем для представления каждого узла дерева и переведите алгоритмы, изложенные в книге, на Perl. Обычно это задача оказывается проще, чем кажется. Программа в примере 11.1 демонстрирует простую реализацию бинарного дерева, построенную на базе анонимных хэшей. Каждый узел состоит из трех полей: левый потомок, правый потомок и значение. Важнейшее свойство упорядоченных бинарных деревьев заключается в том, что значение левого потомка всегда меньше, чем значение текущего узла, а значение правого потомка всегда больше. Основная программа выполняет три операции. Сначала она создает дерево с 20 случайными узлами, затем выводит три варианта обхода узлов дерева и, наконец, запрашивает у пользователя ключ и сообщает, присутствует ли этот ключ в дереве. Функция insert использует механизм неявной передачи скаляров по ссылке для инициализации пустого дерева при вставке пустого узла. Присваивание $ [0] созданного узла приводит к изменению значения на вызывающей стороне. Хотя такая структура данных занимает гораздо больше памяти, чем простой хэш, и обычный перебор элементов в ней происходит медленнее, упорядоченные перемещения выполняются быстрее. Исходный текст программы приведен в примере 11.1. Пример 11.1. bintree #!/usr/bin/perl -w # bintree - пример работы с бинарным деревом use strict; my($root, $n); # Сгенерировать 20 случайных узлов while ($п++ < 20) { insert($root, int(rand(1000)) ) # Вывести узлы дерева в трех разных порядках print "Pre order: "; pre order($root); print "\n" print "In order: "; in order($root); print "\n" print "Post order: "; post order($root); print "\n" # Запрашивать до получения EOF for (print Search "; <>; print "Search ") { chomp; my Sfound = search($root, $ ); if ($found) { print "Found $ at Sfound, $found->{VALUE}\n" else { print "No $ in tree\n" } exit; ######################################### # Функция вставляет передаваемое значение в правильную позицию # передаваемого дерева. Если дерево не передается, # для @ используется механизм косвенной передачи по ссылке, # что приводит к созданию дерева на вызывающей стороне, sub insert { my($tree, $value) = unless ($tree) { Stree = {), $tree->{VALUE} $tree->{LEFT} $tree->{RIGHT} $ [0] = Stree; return; = Svalue; = undef; = undef; # Создать новый узел # S [0] - ссылочный параметр! if (Stree->{VALUE} > Svalue) { insert($tree->{LEFT}, Svalue) } elsif (Stree->{VALUE} < Svalue) { insert(Stree->{RIGHT}, Svalue) } else { warn "dup insert of Svalue\n" } # XXX; узлы не должны повторяться # Рекурсия по левому потомку, # вывод текущего значения # и рекурсия по правому потомку, sub in order { my($tree) = (а ; return unless Stree; in order(Stree->{LEFT}); print Stree->{VALUE}, " "; in order(Stree->{RIGHT}); 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 240 241 242 |