Programming Taskbook 0
Download 1.62 Mb. Pdf ko'rish
|
Abramyan-Pascal2016-1
Глава 3. Массивы и последовательности 37 var a: sequence of integer; Таким образом, все элементы последовательности (как и массива) имеют одинаковый тип. Особой конструкции для инициализатора последовательности не предусмотрено, однако для последовательностей можно использовать тот же набор функций-генераторов, что и для массивов (эти функции подроб- но описывались в предыдущем пункте); требуется лишь изменить префикс «Arr» в именах этих функций на префикс «Seq». Таким образом, для гене- рации последовательностей можно использовать функции Seq (еще один пример короткой функции, допускающей указание произвольного количе- ства однотипных параметров), SeqFill, SeqGen, SeqRandomInteger (имеет ко- роткий синоним SeqRandom) и SeqRandomReal с теми же наборами парамет- ров. Дополнительные возможности, связанные с генерацией последова- тельностей, будут рассмотрены в следующем пункте. Главной особенностью последовательностей является то, что они не выделяют памяти для хранения своих элементов. Точнее, память не выде- ляется для каждого элемента, вместо этого последовательность хранит в памяти информацию о том, как получить каждое значение при необходи- мости. Проиллюстрируем эту особенность на примере. Предположим, что последовательность a определена следующим образом: var a := SeqFill(1000000000, 1); Если бы вместо SeqFill была использована функция ArrFill, то программа попыталась бы выделить память для хранения миллиарда целочисленных элементов, что привело бы при выполнении программы к ее аварийному завершению из-за нехватки памяти. В то же время функция SeqFill с такими же параметрами будет успешно выполнена, и последовательность a будет создана. Однако храниться в этой последовательности будет не миллиард единиц, а информация (в специальном формате) о том, что при необходи- мости из этой последовательности можно извлечь миллиард элементов, каждый из которых будет равен единице. Подчеркнем, что сами элементы нигде не хранятся; они будут созданы тогда, когда потребуется их исполь- зовать, но и в этом случае они будут создаваться не одновременно, а по очереди, т. е. по мере их использования. Простейший способ использования элементов последовательности — их перебор в цикле foreach. Например, к предыдущему оператору можно добавить следующий фрагмент: var sum := 0; foreach var e in a do sum += e; sum.Print; 38 После запуска такой программы через некоторое время (порядка 10– 30 секунд) она выведет число 1000000000. Таким образом, в цикле были об- работаны все элементы последовательности, причем одновременно в памя- ти они не размещались (как мы знаем, это привело бы к аварийному за- вершению программы). Еще одной важной особенностью последовательностей является их неизменяемость (ранее мы отмечали, что эта особенность имеется и у кор- тежей — см. п. 1.4). У последовательности нельзя изменить какой-либо от- дельный элемент; можно лишь преобразовать всю последовательность, по- лучив в результату новую последовательность. Основным способом преобразования последовательности является применение к ней некоторого запроса — метода, обычно возвращающего новую последовательность (хотя имеются запросы, возвращающие скаляр- ные данные или другие структуры, например массивы). Запросы, преобра- зующие одну последовательность в другую, как правило, не обрабатывают сразу каждый элемент исходной последовательности; вместо этого они в специальном формате описывают то преобразование, которое надо приме- нить к элементам, «откладывая» фактическое выполнение преобразования «на потом» — к моменту, когда, например, потребуется организовать пе- ребор полученной последовательности в цикле foreach. Запросы для после- довательностей будут подробно обсуждаться далее (см. главу 4), а сейчас для иллюстрации их особенностей мы используем один из самых распро- страненных запросов — Select, который преобразует все элементы исход- ной последовательности в соответствующие элементы новой последова- тельности по определенному правилу (задаваемому в виде лямбда- выражения). Вернемся к предыдущему примеру и применим к созданной последо- вательности запрос Select. Кроме того, уменьшим размер последовательно- сти в 10 раз (с 1 миллиарда до 100 миллионов элементов) и добавим в ко- нец фрагмента вывод времени работы программы (в миллисекундах), ис- пользовав для этого стандартную функцию Milliseconds: // Вариант 1 var a := SeqFill(100000000, 1).Select(e -> 2 * e); var sum := 0; foreach var e in a do sum += e; Print(sum, Milliseconds); Download 1.62 Mb. Do'stlaringiz bilan baham: |
Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling
ma'muriyatiga murojaat qiling