Programming Taskbook 0
Download 1.62 Mb. Pdf ko'rish
|
Abramyan-Pascal2016-1
0
0.01 0.04 0.09 0.16 0.25 0.36 0.49 0.64 0.81 1 1 0.81 0.64 0.49 0.36 0.25 0.16 0.09 0.04 0.01 0 Глава 3. Массивы и последовательности 45 Завершив на этом обсуждение функции Range, обратимся к функции SeqWhile. Она имеет два перегруженных варианта со следующими заголов- ками (напомним, что мы условились для краткости не указывать текст после имени обобщенной функции): function SeqWhile(first: T; next: T -> T; pred: T -> boolean): sequence of T function SeqWhile(first, second: T; next: (T,T) -> T; pred: T -> boolean): sequence of T Данная функция имеет в числе своих параметров два лямбда-выраже- ния. Первое из них, next, определяет правило, по которому следующий элемент последовательности будет сгенерирован на основе одного или двух предыдущих, а второе, pred (от слова predicate — предикат), опреде- ляет, когда следует прекратить заполнение последовательности. Последо- вательность заполняется до тех пор, пока предикат pred возвращает True для очередного значения, полученного функцией next; только в этом случае полученное значение добавляется в последовательность. Как только значе- ние, возвращенное функцией next, перестанет удовлетворять предикату, построение последовательности завершится; таким образом, можно утвер- ждать, что все элементы полученной последовательности будут удовле- творять предикату pred. Параметры first и second функции SeqWhile задают начальные значения формируемой последовательности (одно, если рекур- рентная формула next использует одно предыдущее значение, и два, если формула next использует два предыдущих значения). Эти начальные значе- ния также проверяются предикатом pred; если, например, для параметра first предикат pred вернет значение False, то функция SeqWhile вернет пу- стую последовательность. Интересной особенностью функции SeqWhile является то, что при ее вызове неизвестен размер той последовательности, которую она создаст. Это отличает ее от всех функций-генераторов, которые являются общими для массивов и последовательностей (ArrFill и SeqFill, ArrGen и SeqGen, ArrRandom и SeqRandom и т. п.). Во всех функциях-генераторах массивов вначале выделяется память для хранения элементов массива, а затем они заполняются по тому или иному алгоритму. Именно поэтому в наборе ге- нераторов для массивов отсутствует аналог функции SeqWhile: любая реа- лизация подобного генератора для массива была бы неэффективной. В случае же последовательностей никаких проблем с реализацией функции SeqWhile не возникает, поскольку при генерации последователь- ности ее элементы не размещаются в памяти. Фактический перебор эле- ментов последовательности выполняется либо в цикле foreach, либо при выполнении некоторых видов запросов (например, уже использовавшегося 46 нами запроса Sum), либо при ее выводе с помощью соответствующих про- цедур или методов. При анализе функции SeqWhile можно задаться таким вопросом: что произойдет, если предикат pred никогда не вернет значение False? Если бы предикат использовался в качестве условия обычного цикла while, то про- изошло бы зацикливание программы. В нашем случае ситуация будет ин- тереснее: последовательность будет успешно создана (поскольку для ее со- здания не требуется генерировать все ее элементы; достаточно сохранить каким-либо образом способ их генерации). Проблемы возникнут при по- пытке перебрать все элементы этой «бесконечной» последовательности. Предположим, например, что мы создадим с помощью функции Se- qWhile бесконечную последовательность Фибоначчи: var fib := SeqWhile(1.0, 1.0, (a, b) -> a + b, e -> True); Для того чтобы в этой последовательности правильно вычислялись числа Фибоначчи с большими номерами, мы указали в качестве начальных значений вещественные числа. Данный оператор успешно откомпилируется и не приведет к каким- либо проблемам при запуске программы. Однако при попытке вывести элементы этой последовательности в цикле foreach мы, как и следовало ожидать, получим зациклившуюся программу. Зацикливание произойдет и при попытке подсчитать, например, сумму всех элементов нашей последо- вательности с помощью вызова fib.Sum. 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