Programming Taskbook 0


Download 1.62 Mb.
Pdf ko'rish
bet40/71
Sana21.06.2023
Hajmi1.62 Mb.
#1644761
TuriУчебное пособие
1   ...   36   37   38   39   40   41   42   43   ...   71
Bog'liq
Abramyan-Pascal2016-1


Глава 4. Запросы 
65 
При решении задачи мы использовали запросы First и Last с парамет-
рами-предикатами. Поскольку для исходной последовательности требова-
лось вызвать два запроса, пришлось связать с ней идентификатор a.
Замечание. Полезно напомнить, что произошло бы, если бы послед-
ний оператор был включен в «обычную» программу, не связанную с за-
дачником, в которой последовательность a вводится с помощью одного из 
вариантов функции ReadSeqInteger, входящих в стандартную библиотеку 
PascalABC.NET (например, ReadSeqInteger(10)). В этом случае потребова-
лось бы дважды вводить элементы исходной последовательности с клави-
атуры — при выполнении каждого из использованных в последнем опера-
торе запросов. Чтобы подобные проблемы при выполнении заданий не 
возникали (и не приводили к сообщениям вида «Попытка ввода лишних 
исходных данных»), функции ввода последовательностей в модуле PT4 бы-
ли специальным образом модифицированы (см. последнее замечание в 
п. 3.7). 
В задаче LinqBegin2 дается цифра d и целочисленная последователь-
ность. Требуется вывести первый положительный элемент, оканчиваю-
щийся цифрой d, или число 0, если таких элементов в последовательности 
нет: 
Task('LinqBegin2');
var d := ReadInteger; 
Write(ReadSeqInteger.FirstOrDefault(e -> (e > 0)
and (e mod 10 = d))); 
В данном случае, поскольку требуемый элемент может отсутствовать, 
необходимо использовать запрос с суффиксом OrDefault. Мы не стали свя-
зывать введенную последовательность с переменной, сразу применив к 
функции ReadSeqInteger требуемый запрос. 
В задаче LinqBegin9 требуется вывести минимальный положительный 
элемент целочисленной последовательности или число 0, если последова-
тельность не содержит положительных элементов.
Один из очевидных вариантов решения этой задачи — предваритель-
ная фильтрация исходной последовательности (см. следующий пункт), 
однако можно обойтись и теми средствами, которые описаны в данном 
пункте. Придется лишь дополнительно проанализировать результат, воз-
вращенный запросом: 
Task('LinqBegin9');
var a := ReadSeqInteger.Min(e -> e <= 0 ? integer.MaxValue : e); 
Write(a = integer.MaxValue ? 0 : a); 
В запросе Min мы использовали селектор, который сохраняет неизмен-
ными все положительные элементы последовательности, а отрицательные 
заменяет на максимальное значение типа integer (доступное в виде свойства 


66 
integer.MaxValue). Для этого мы использовали в селекторе тернарную опе-
рацию вида условие ? значение1 : значение2, которая вычисляет условие и 
возвращает значение1, если условие истинно, и значение2, если условие 
ложно (синтаксис тернарной операции заимствован языком Pascal-
ABC.NET из языков семейства C). 
Если в последовательности имеется хотя бы один положительный 
элемент, то запрос Min вернет минимальный из таких элементов, а если по-
ложительных элементов в последовательности нет, то будет возвращено 
значение integer.MaxValue. В этом особом случае программа выводит число 
0 (еще раз используя тернарную операцию). 
В задании LinqBegin15 требуется вычислить факториал N! целого 
числа N (равный произведению всех целых чисел от 1 до NN! = 12…N), 
используя генератор Range (описанный в начале п. 3.5) и запрос Aggregate. 
При этом факториал требуется вычислять в виде вещественного числа
чтобы избежать целочисленного переполнения для больших значений N
Task('LinqBegin15');
Write(Range(1, ReadInteger).Aggregate(1.0, (a, e) -> a * e)); 
Главной особенностью этого решения является использование второго 
из вариантов запроса Aggregate, в котором указывается начальное значение 
аккумулятора в виде 1.0 (т. е. вещественной единицы). Заметим, что запрос 
Aggregate((a, e) -> a * e) тоже позволяет правильно вычислять факториал 
(в виде целого числа), но только в ситуации, когда значение факториала не 
превосходит максимального значения для типа integer (в противном случае 
из-за целочисленного переполнения будет получено неверное число, кото-
рое, в частности, может оказаться отрицательным). 
4.2.
Фильтрация, сортировка, комбинирование 
и расщепление 
В данном пункте мы рассмотрим запросы, позволяющие извлекать из 
исходной последовательности требуемые элементы (фильтрация), изме-
нять порядок следования элементов (сортировка и инвертирование), объ-
единять элементы нескольких последовательностей в одну и, наоборот, 
расщеплять исходную последовательность на две.
Все запросы этих групп возвращают новые последовательности (или 
кортежи из двух последовательностей), тип элементов которых совпадает 
с типом элементов исходных последовательностей. Как и все запросы, воз-
вращающие последовательности, они характеризуются «отложенным» вы-
полнением: реальное формирование элементов полученных последова-
тельностей будет происходить только при последующем переборе этих 
элементов (в цикле foreach, при печати или при преобразовании последова-


Download 1.62 Mb.

Do'stlaringiz bilan baham:
1   ...   36   37   38   39   40   41   42   43   ...   71




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling