Массивы (PascalABC.NET): различия между версиями
(не показаны 34 промежуточные версии этого же участника) | |||
Строка 38: | Строка 38: | ||
var a: array[0..12] of byte; // 13 элементов byte | var a: array[0..12] of byte; // 13 элементов byte | ||
var b, c: array[-5..8] of real; // два массива по 14 элементов real | var b, c: array[-5..8] of real; // два массива по 14 элементов real | ||
− | |||
var a: array[3..6] of integer := (1, 2, 3, 4); | var a: array[3..6] of integer := (1, 2, 3, 4); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Динамические массивы === | === Динамические массивы === | ||
− | Описание и инициализация динамического массива отличаются лишь тем, что границы индексов не | + | Описание и инициализация динамического массива отличаются лишь тем, что границы индексов не указываются. Вследствие этого компилятор не может отвести место под такой массив и необходимая память выделяется во время выполнения программы. |
<syntaxhighlight lang="pascal" line> | <syntaxhighlight lang="pascal" line> | ||
var a1: array of integer; // массив целых чисел | var a1: array of integer; // массив целых чисел | ||
Строка 81: | Строка 80: | ||
== Перебор элементов в цикле == | == Перебор элементов в цикле == | ||
− | === Перебор с помощью цикла с | + | === Перебор с помощью цикла с параметром === |
<syntaxhighlight lang="pascal" line> | <syntaxhighlight lang="pascal" line> | ||
Begin | Begin | ||
Строка 105: | Строка 104: | ||
== Вывод массива == | == Вывод массива == | ||
− | === Вывод массива с помощью цикла с параметром === | + | === Вывод массива на одной строке с помощью цикла с параметром === |
<syntaxhighlight lang="pascal" line> | <syntaxhighlight lang="pascal" line> | ||
Begin | Begin | ||
Строка 114: | Строка 113: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | === Вывод массива методом Print === | + | === Вывод массива на одной строке методом Print === |
Метод предполагает необязательный параметр обозначающий разделитель. | Метод предполагает необязательный параметр обозначающий разделитель. | ||
<syntaxhighlight lang="pascal" line> | <syntaxhighlight lang="pascal" line> | ||
Строка 121: | Строка 120: | ||
a.Println(); | a.Println(); | ||
a.Println(', '); | a.Println(', '); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Вывод массива по одному значению в строке с помощью цикла с параметром === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a := ArrRandom(10, 10, 30); | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | Writeln(a[i]); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Вывод массива по одному значению в строке методом PrintLines === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a := ArrRandom(10, 10, 30); | ||
+ | a.PrintLines; | ||
end. | end. | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Строка 139: | Строка 155: | ||
Begin | Begin | ||
var a:= ReadArrInteger(15); | var a:= ReadArrInteger(15); | ||
+ | end. | ||
+ | |||
+ | Begin | ||
+ | var a:= ReadArrReal(5); | ||
end. | end. | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Строка 149: | Строка 169: | ||
Лямбда-выражение можно записать в переменную. | Лямбда-выражение можно записать в переменную. | ||
− | Пример лямбда-выражения | + | Пример лямбда-выражения обозначающего подпрограмму (которая принимает целое число в качестве параметра и возвращает целое число) увеличивающую число в 2 раза. |
<syntaxhighlight lang="pascal" line> | <syntaxhighlight lang="pascal" line> | ||
var x: integer -> integer := t -> 2 * t; | var x: integer -> integer := t -> 2 * t; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | |||
== Фильтрация == | == Фильтрация == | ||
Строка 186: | Строка 205: | ||
var a:= ArrRandom(10, -10, 10); | var a:= ArrRandom(10, -10, 10); | ||
a.Println; | a.Println; | ||
− | var b := a.Where(x -> x > 0); | + | var b := a.Where(x -> x > 0).ToArray; |
+ | b.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Фильтрация по нескольким условиям с помощью цикла с параметром и условного оператора === | ||
+ | Пример который выделяет в новый массив только положительные делящиеся на три без остатка числа из изначального массива. | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | var b := new integer[a.Length]; | ||
+ | var index := 0; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | begin | ||
+ | if (a[i] > 0) and (a[i] mod 3 = 0) then | ||
+ | begin | ||
+ | b[index] := a[i]; | ||
+ | index += 1; | ||
+ | end; | ||
+ | end; | ||
+ | SetLength(b, index); | ||
+ | b.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | === Фильтрация по нескольким условиям с помощью метода Where === | ||
+ | Пример который выделяет в новый массив только положительные делящиеся на три без остатка числа из изначального массива. | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | var b := a.Where(x -> (x > 0) and (x mod 3 = 0)).ToArray; | ||
+ | b.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Where с двумя параметрами: элемент + индекс === | ||
+ | В метод Where можно передать функцию не только с одним параметром, но и с двумя. В таком случае первое значение будет самим элементом, а второе индексом массива. Например, можно вывести элементы с чётными индексами. | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a := ArrRandom(10, -20, 20); | ||
+ | a.Println; | ||
+ | a.Where((x,i) -> i mod 2 = 0).Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Проекция == | ||
+ | Проецирование сохраняет исходное количество элементов последовательности, но преобразовывает каждый элемент по некоторому правилу. Аналог – мясорубка. На входе мясо – на выходе фарш, причем именно из этого мяса. Проецирование осуществляет функция, преобразующая входные элементы по правилу, заданному лямбда-выражением. | ||
+ | |||
+ | Вы можете реализовать трансформацию всех элементов массива с помощью цикла с параметром и оператора присваивания. | ||
+ | |||
+ | === Проекция с помощью цикла с параметром === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | var b := new integer[a.Length]; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | b[i] := a[i] * a[i]; | ||
+ | b.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Проекция с помощью метода Select === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | var b := a.Select(x -> x*x); | ||
+ | b.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Select с двумя параметрами: элемент + индекс === | ||
+ | В метод Select можно передать функцию не только с одним параметром, но и с двумя. В таком случае первое значение будет самим элементом, а второе индексом массива. Например, можно увеличить элементы массива на индекс элемента. | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a := ArrRandom(10, -20, 20); | ||
+ | a.Println; | ||
+ | a.Select((x,i) -> x + i).Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Сумма == | ||
+ | === Сумма циклом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | var sum := 0; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | sum := sum + a[i]; | ||
+ | Writeln(sum); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Сумма методом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | Writeln(a.Sum); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Произведение == | ||
+ | === Произведение циклом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(3, -10, 10); | ||
+ | a.Println; | ||
+ | var prod := 1; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | prod := prod * a[i]; | ||
+ | Writeln(prod); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | === Произведение методом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(3, -10, 10); | ||
+ | a.Println; | ||
+ | Writeln(a.Product); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Минимум == | ||
+ | === Минимум циклом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | var min := integer.MaxValue; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | begin | ||
+ | if a[i] < min then min := a[i]; | ||
+ | end; | ||
+ | Writeln(min); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Минимум методом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | Writeln(a.Min); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Максимум == | ||
+ | === Максимум циклом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | var max := integer.MinValue; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | begin | ||
+ | if a[i] > max then max := a[i]; | ||
+ | end; | ||
+ | Writeln(max); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Максимум методом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | Writeln(a.Max); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Среднее == | ||
+ | === Среднее циклом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | var sum := 0; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | sum := sum + a[i]; | ||
+ | Writeln(sum / a.Length); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Среднее методами === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | Writeln(a.Sum / a.Length); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Среднее методом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | Writeln(a.Average); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Заполнение массива одинаковыми значениями == | ||
+ | === Заполнение с помощью цикла с параметром === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a := new integer[10]; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | a[i] := 42; | ||
+ | a.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Заполнение функцией или умножением === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrFill(10, 42); | ||
+ | a.Println; | ||
+ | var b := |77| * 5; | ||
b.Println; | b.Println; | ||
end. | end. | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | == Заполнение массива случайными значениями == | ||
+ | === Заполнение с помощью цикла с параметром === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a := new integer[10]; | ||
+ | for var i := 0 to a.Length - 1 do | ||
+ | a[i] := Random(-50, 50); | ||
+ | a.Println(); | ||
+ | |||
+ | var b := new real[10]; | ||
+ | for var i := 0 to b.Length - 1 do | ||
+ | b[i] := Random(-5.0, 5.0); | ||
+ | b.Println(); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | === Заполнение методом === | ||
<syntaxhighlight lang="pascal" line> | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -50, 50); | ||
+ | a.Println; | ||
+ | var b := ArrRandomReal(10, -5, 5); | ||
+ | b.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Генерация массивов на основе лямбда-выражений == | ||
+ | === n значений из индекса от 0 === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrGen(5, i -> 2 * i + 1); | ||
+ | a.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === n значений из индекса начиная с m === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrGen(3, i -> 2 * i + 1, 10); | ||
+ | a.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Рекуррентная последовательность с заданным первым элементом и количеством элементов == | ||
+ | === Циклом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | begin | ||
+ | var a := new integer[3]; | ||
+ | var x := 105; | ||
+ | var delta := 7; | ||
+ | for var i := 0 to a.Length - 1 do | ||
+ | begin | ||
+ | a[i] := x; | ||
+ | x += delta; | ||
+ | end; | ||
+ | a.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Методом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrGen(3, 105, i -> i + 7); | ||
+ | a.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Количество элементов, удовлетворяющих условию == | ||
+ | === Циклом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | begin | ||
+ | var a := ArrRandom(10, -50, 50); | ||
+ | a.Println; | ||
+ | var count := 0; | ||
+ | for var i := 0 to a.Length - 1 do | ||
+ | begin | ||
+ | if a[i] > 0 then count += 1; | ||
+ | end; | ||
+ | Writeln(count); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Методом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -50, 50); | ||
+ | a.Println; | ||
+ | Writeln(a.Count(x -> x > 0)); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Уникальные элементы последовательности == | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, 0, 10); | ||
+ | a.Println; | ||
+ | a.Distinct.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Сортировка == | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, 0, 10); | ||
+ | a.Println; | ||
+ | a.Sorted.Println; | ||
+ | a.SortedDescending.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Последовательность в обратном порядке == | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, 0, 10); | ||
+ | a.Println; | ||
+ | a.Reverse.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Срезы (выделение части массива) == | ||
+ | <blockquote> | ||
+ | a[:5] – пять первых элементов массива (индексы 0..4); | ||
+ | |||
+ | a[3:] – элементы массива, начиная с a[3] и до конца; | ||
+ | |||
+ | a[2:7] – элементы массива, начиная с a[2] и заканчивая a[6]; | ||
+ | |||
+ | a[::] – весь массив (эквивалентно просто a); | ||
+ | |||
+ | a[::2] – элементы массива c индексами 0, 2, 4, … (четными); | ||
+ | |||
+ | a[1::2] – элементы массива c индексами 1, 3, 5, … (нечетными); | ||
+ | |||
+ | a[4:13:3] – элементы массива с индексами 4, 7, 10; | ||
+ | |||
+ | a[13:4:-3] – элементы массива с индексами 13, 10, 7; | ||
+ | |||
+ | a[::-1] – элементы массива в обратном порядке. | ||
+ | </blockquote> | ||
+ | |||
+ | Можно указывать срезы, в которых отсчет ведется от конца массива, для чего перед значением индекса ставится знак ^. При этом a[^1] – это последний элемент массива a, a[^2] предпоследний элемент и т.д. Элемента с индексом [^0] не существует! | ||
+ | |||
+ | <blockquote> | ||
+ | a[^5:] – пять последних элементов массива a; | ||
+ | |||
+ | a[^1:^6:-1] – то же, но взятые в обратном порядке; | ||
+ | |||
+ | a[:^5] – все элементы массива a, кроме пяти последних | ||
+ | </blockquote> | ||
+ | |||
+ | == Проверка есть ли элемент в последовательности == | ||
+ | === Проверка с помощью цикла с параметром === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, 0, 10); | ||
+ | a.Println; | ||
+ | var x := 5; | ||
+ | var exists := False; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | if a[i] = x then exists := True; | ||
+ | Writeln(exists); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Проверка с помощью метода === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, 0, 10); | ||
+ | a.Println; | ||
+ | var x := 5; | ||
+ | Writeln(a.Contains(x)); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Проверка есть ли в последовательности элемент удовлетворяющий условию == | ||
+ | === Проверка с помощью цикла с параметром === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -1, 10); | ||
+ | a.Println; | ||
+ | var any := false; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | begin | ||
+ | if a[i] < 0 then | ||
+ | any := true; | ||
+ | end; | ||
+ | Writeln(any); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Проверка с помощью метода === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -1, 10); | ||
+ | a.Println; | ||
+ | Writeln(a.Any(x -> x < 0)); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Проверка все ли элементы последовательности удовлетворяют условию == | ||
+ | === Проверка с помощью цикла с параметром === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -1, 10); | ||
+ | a.Println; | ||
+ | var any := true; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | begin | ||
+ | if a[i] >= 0 then | ||
+ | any := false; | ||
+ | end; | ||
+ | Writeln(any); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Проверка с помощью метода === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -1, 10); | ||
+ | a.Println; | ||
+ | Writeln(a.All(x -> x >= 0)); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Поиск индексов минимального или максимального элементов == | ||
+ | === Поиск индекса минимального элемента циклом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -1, 10); | ||
+ | a.Println; | ||
+ | var min := integer.MaxValue; | ||
+ | var indexMin := -1; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | begin | ||
+ | if (a[i] < min) then | ||
+ | begin | ||
+ | min := a[i]; | ||
+ | indexMin := i; | ||
+ | end; | ||
+ | end; | ||
+ | Writeln(indexMin); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Поиск индекса минимального элемента методом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -1, 10); | ||
+ | a.Println; | ||
+ | Writeln(a.IndexMin); | ||
+ | Writeln(a.LastIndexMin); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Поиск индекса максимального элемента циклом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -1, 10); | ||
+ | a.Println; | ||
+ | var max := integer.MinValue; | ||
+ | var indexMax := -1; | ||
+ | for var i := 0 to a.Length-1 do | ||
+ | begin | ||
+ | if (a[i] > max) then | ||
+ | begin | ||
+ | max := a[i]; | ||
+ | indexMax := i; | ||
+ | end; | ||
+ | end; | ||
+ | Writeln(indexMax); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Поиск индекса максимального элемента методом === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a:= ArrRandom(10, -1, 10); | ||
+ | a.Println; | ||
+ | Writeln(a.IndexMax); | ||
+ | Writeln(a.LastIndexMax); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Пересечение (общие элементы) двух массивов == | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a := ArrRandom(10, -10, 10); | ||
+ | var b := ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | b.Println; | ||
+ | a.Intersect(b).Println(); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Объединение (все уникальные элементы) двух массивов == | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a := ArrRandom(10, -10, 10); | ||
+ | var b := ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | b.Println; | ||
+ | a.Union(b).Println(); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Разность двух массивов (элементы первого массива, которых нет во втором) == | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a := ArrRandom(10, -10, 10); | ||
+ | var b := ArrRandom(10, -10, 10); | ||
+ | a.Println; | ||
+ | b.Println; | ||
+ | a.Except(b).Println(); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Объединение методов == | ||
+ | Большинство методов для обработки последовательностей возвращает последовательность в виде результата. К ней в свою очередь можно применить те же методы, что позволяет применять несколько методов в одном вызове. Если строка вызовов становится длинной её разбивают выделяя каждый новый метод на новую строку, которая начинается с точки. Все строки, кроме первой, пишутся с отступом, чтобы показать принадлежность к одной строке кода. | ||
+ | |||
+ | === Сумма положительных элементов === | ||
+ | Например сначала можно отобрать из массива только положительные элементы, затем найти их сумму и третьим методом вывести её на экран. | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a := ArrRandom(10, -20, 20); | ||
+ | a.Println; | ||
+ | a.Where(x -> x > 0).Sum.Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Квадраты элементов, которые больше 5 === | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a := ArrRandom(10, -20, 20); | ||
+ | a.Println; | ||
+ | a.Where(x -> x > 5) | ||
+ | .Select(x -> x * x) | ||
+ | .Println; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Сумма индексов чётных чисел === | ||
+ | Например, мы можем преобразовать список чисел в список пар (кортежей) чисел и их индексов (.Select((x,i) -> (x,i))). Затем пары чисел можно обрабатывать как одну переменную пары. Эта пара является кортежем. Вы можете упаковать до 7 переменных. Доступ к элементам кортежа происходит через свойства Item1, Item2 и так далее. Или вы можете распаковать кортеж в переменные с помощью слэша \ (например, \(x,i)). Тогда первая переменная будет записана в переменную x, а вторая в переменную i. | ||
+ | <syntaxhighlight lang="pascal" line> | ||
+ | Begin | ||
+ | var a := ArrRandom(10, -20, 20); | ||
+ | a.Println; | ||
+ | a.Select((x,i) -> (x,i)) | ||
+ | .Where(pair -> pair.Item1 mod 2 = 0) | ||
+ | .Select(\(x,i) -> i) | ||
+ | .Sum.Println; | ||
+ | end. | ||
</syntaxhighlight> | </syntaxhighlight> |
Текущая версия на 17:12, 15 апреля 2024
Pascal ABC.NET выбор школьника - Часть 2
Массив
Массив – хранимая нумерованная последовательность однотипных элементов с непосредственным доступом к любому элементу по его индексам, являющимся своеобразным аналогом номера.
Статические и динамические массивы
Статические массивы
Память под статический массив распределяется на этапе компиляции программы. Одновременно может быть выполнена инициализация элементов массива. Границы индексов статического массива неизменны и должны быть указаны в программе константами или выражениями, содержащими только константы.
Статические массивы – дань совместимости с более ранними версиями языка Паскаль.
Длину статического массива нельзя менять.
Динамические массивы
Динамический массив нужного размера может быть создан в том месте программы, где он впервые потребуется.
В динамических массивах индексы начинаются от нуля.
Количество элементов в динамическом массиве может меняться, но никогда не может стать отрицательным. Текущее количество элементов в массиве хранится в поле .Length.
Первый элемент массива всегда имеет индекс ноль.
Создание и инициализация массива
Статические массивы
Статический массив обычно описывается в виде
var ИмяМассива: array[m..n] of ТипЭлементов;
1 var a: array[0..12] of byte; // 13 элементов byte
2 var b, c: array[-5..8] of real; // два массива по 14 элементов real
3 var a: array[3..6] of integer := (1, 2, 3, 4);
Динамические массивы
Описание и инициализация динамического массива отличаются лишь тем, что границы индексов не указываются. Вследствие этого компилятор не может отвести место под такой массив и необходимая память выделяется во время выполнения программы.
1 var a1: array of integer; // массив целых чисел
2 var p: array of real; // массив вещественных чисел
3 var q: array of boolean; // массив логических элементов
Проще всего создать динамический массив при помощи функции Arr, возвращающей такой массив. Ее аргументы – единого типа перечисленные через запятую члены будущего массива. Вместо Arr( ) удобно использовать более короткую конструкцию | |.
1 var a := Arr(1, 9, -4, 12, 40, 39, 54);
2 var d := |1, 9, -4, 12, 40, 39, 54|; // альтернативный вариант
3 var b := |3.5, 2.0, 6.417, -12.0|;
4 var c := Arr(True, 3.5 > 1.63 ** 2.95, Sin(x) > 1, False, False);
Можно совместить описание динамического массива с его созданием, для чего потребуется указать необходимую длину массива.
1 var a := new integer[10]; // массив из 10 целых элементов
2 var b := new real[7]; // массив из 7 вещественных элементов
3 var c := new boolean[4]; // массив из 4 логических элементов
Можно создать массив и обнулить его элементы следующим образом:
1 var a := |0| * 15; // создан массив из 15 нулевых элементов
В случае, когда массив был описан заранее, его длину можно установить (либо поменять) вызовом процедуры SetLength.
1 var a1: array of integer; // массив целых
2 SetLength(a1, 13); // установлена длина массива a1, равная 13
Перебор элементов в цикле
Перебор с помощью цикла с параметром
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 for var i := 0 to a.Length-1 do
4 begin
5 // a[i]
6 end;
7 end.
Перебор с помощью цикла foreach
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 foreach var x in a do
4 begin
5 // x
6 end;
7 end.
Вывод массива
Вывод массива на одной строке с помощью цикла с параметром
1 Begin
2 var a:= new integer[15];
3 for var i := 0 to a.Length-1 do
4 Write(a[i], ' ');
5 end.
Вывод массива на одной строке методом Print
Метод предполагает необязательный параметр обозначающий разделитель.
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println();
4 a.Println(', ');
5 end.
Вывод массива по одному значению в строке с помощью цикла с параметром
1 Begin
2 var a := ArrRandom(10, 10, 30);
3 for var i := 0 to a.Length-1 do
4 Writeln(a[i]);
5 end.
Вывод массива по одному значению в строке методом PrintLines
1 Begin
2 var a := ArrRandom(10, 10, 30);
3 a.PrintLines;
4 end.
Ввод элементов с клавиатуры
Ввод элементов массива с помощью цикла с параметром
1 Begin
2 var a:= new integer[15];
3 for var i := 0 to a.Length-1 do
4 Readln(a[i]);
5 end.
Ввод элементов массива с помощью функции
Единственный аргумент данной функции это количество вводимых элементов.
1 Begin
2 var a:= ReadArrInteger(15);
3 end.
4
5 Begin
6 var a:= ReadArrReal(5);
7 end.
Лямбда-выражения
Лямбда-выражения (или просто лямбды) – термин функционального программирования. Они с успехом применяются вместо уже привычных вам процедур и функций. Собственно, они и есть процедуры или функции, только безымянные.
Лямбда-выражение представляет собой некоторое безымянное выражение, отражающее функциональную зависимость. Упрощенно, на его основе компилятор строит функцию, некоторым образом идентифицирует ее и подменяет этим идентификатором лямбда-выражение.
Лямбда-выражение можно записать в переменную.
Пример лямбда-выражения обозначающего подпрограмму (которая принимает целое число в качестве параметра и возвращает целое число) увеличивающую число в 2 раза.
1 var x: integer -> integer := t -> 2 * t;
Фильтрация
В программировании фильтруют обрабатываемые данные. Лишь прошедшие через фильтр данные примут участие в дальнейшей обработке.
Вы можете реализовать фильтрацию элементов массива с помощью циклов и условного оператора или с помощью функций-методов массивов.
Фильтрация с помощью цикла с параметром и условного оператора
Пример который выделяет в новый массив только положительные числа из изначального массива.
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 var b := new integer[a.Length];
5 var index := 0;
6 for var i := 0 to a.Length-1 do
7 begin
8 if (a[i] > 0) then
9 begin
10 b[index] := a[i];
11 index += 1;
12 end;
13 end;
14 SetLength(b, index);
15 b.Println;
16 end.
Фильтрация с помощью метода Where
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 var b := a.Where(x -> x > 0).ToArray;
5 b.Println;
6 end.
Фильтрация по нескольким условиям с помощью цикла с параметром и условного оператора
Пример который выделяет в новый массив только положительные делящиеся на три без остатка числа из изначального массива.
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 var b := new integer[a.Length];
5 var index := 0;
6 for var i := 0 to a.Length-1 do
7 begin
8 if (a[i] > 0) and (a[i] mod 3 = 0) then
9 begin
10 b[index] := a[i];
11 index += 1;
12 end;
13 end;
14 SetLength(b, index);
15 b.Println;
16 end.
Фильтрация по нескольким условиям с помощью метода Where
Пример который выделяет в новый массив только положительные делящиеся на три без остатка числа из изначального массива.
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 var b := a.Where(x -> (x > 0) and (x mod 3 = 0)).ToArray;
5 b.Println;
6 end.
Where с двумя параметрами: элемент + индекс
В метод Where можно передать функцию не только с одним параметром, но и с двумя. В таком случае первое значение будет самим элементом, а второе индексом массива. Например, можно вывести элементы с чётными индексами.
1 Begin
2 var a := ArrRandom(10, -20, 20);
3 a.Println;
4 a.Where((x,i) -> i mod 2 = 0).Println;
5 end.
Проекция
Проецирование сохраняет исходное количество элементов последовательности, но преобразовывает каждый элемент по некоторому правилу. Аналог – мясорубка. На входе мясо – на выходе фарш, причем именно из этого мяса. Проецирование осуществляет функция, преобразующая входные элементы по правилу, заданному лямбда-выражением.
Вы можете реализовать трансформацию всех элементов массива с помощью цикла с параметром и оператора присваивания.
Проекция с помощью цикла с параметром
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 var b := new integer[a.Length];
5 for var i := 0 to a.Length-1 do
6 b[i] := a[i] * a[i];
7 b.Println;
8 end.
Проекция с помощью метода Select
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 var b := a.Select(x -> x*x);
5 b.Println;
6 end.
Select с двумя параметрами: элемент + индекс
В метод Select можно передать функцию не только с одним параметром, но и с двумя. В таком случае первое значение будет самим элементом, а второе индексом массива. Например, можно увеличить элементы массива на индекс элемента.
1 Begin
2 var a := ArrRandom(10, -20, 20);
3 a.Println;
4 a.Select((x,i) -> x + i).Println;
5 end.
Сумма
Сумма циклом
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 var sum := 0;
5 for var i := 0 to a.Length-1 do
6 sum := sum + a[i];
7 Writeln(sum);
8 end.
Сумма методом
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 Writeln(a.Sum);
5 end.
Произведение
Произведение циклом
1 Begin
2 var a:= ArrRandom(3, -10, 10);
3 a.Println;
4 var prod := 1;
5 for var i := 0 to a.Length-1 do
6 prod := prod * a[i];
7 Writeln(prod);
8 end.
Произведение методом
1 Begin
2 var a:= ArrRandom(3, -10, 10);
3 a.Println;
4 Writeln(a.Product);
5 end.
Минимум
Минимум циклом
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 var min := integer.MaxValue;
5 for var i := 0 to a.Length-1 do
6 begin
7 if a[i] < min then min := a[i];
8 end;
9 Writeln(min);
10 end.
Минимум методом
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 Writeln(a.Min);
5 end.
Максимум
Максимум циклом
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 var max := integer.MinValue;
5 for var i := 0 to a.Length-1 do
6 begin
7 if a[i] > max then max := a[i];
8 end;
9 Writeln(max);
10 end.
Максимум методом
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 Writeln(a.Max);
5 end.
Среднее
Среднее циклом
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 var sum := 0;
5 for var i := 0 to a.Length-1 do
6 sum := sum + a[i];
7 Writeln(sum / a.Length);
8 end.
Среднее методами
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 Writeln(a.Sum / a.Length);
5 end.
Среднее методом
1 Begin
2 var a:= ArrRandom(10, -10, 10);
3 a.Println;
4 Writeln(a.Average);
5 end.
Заполнение массива одинаковыми значениями
Заполнение с помощью цикла с параметром
1 Begin
2 var a := new integer[10];
3 for var i := 0 to a.Length-1 do
4 a[i] := 42;
5 a.Println;
6 end.
Заполнение функцией или умножением
1 Begin
2 var a:= ArrFill(10, 42);
3 a.Println;
4 var b := |77| * 5;
5 b.Println;
6 end.
Заполнение массива случайными значениями
Заполнение с помощью цикла с параметром
1 Begin
2 var a := new integer[10];
3 for var i := 0 to a.Length - 1 do
4 a[i] := Random(-50, 50);
5 a.Println();
6
7 var b := new real[10];
8 for var i := 0 to b.Length - 1 do
9 b[i] := Random(-5.0, 5.0);
10 b.Println();
11 end.
Заполнение методом
1 Begin
2 var a:= ArrRandom(10, -50, 50);
3 a.Println;
4 var b := ArrRandomReal(10, -5, 5);
5 b.Println;
6 end.
Генерация массивов на основе лямбда-выражений
n значений из индекса от 0
1 Begin
2 var a:= ArrGen(5, i -> 2 * i + 1);
3 a.Println;
4 end.
n значений из индекса начиная с m
1 Begin
2 var a:= ArrGen(3, i -> 2 * i + 1, 10);
3 a.Println;
4 end.
Рекуррентная последовательность с заданным первым элементом и количеством элементов
Циклом
1 begin
2 var a := new integer[3];
3 var x := 105;
4 var delta := 7;
5 for var i := 0 to a.Length - 1 do
6 begin
7 a[i] := x;
8 x += delta;
9 end;
10 a.Println;
11 end.
Методом
1 Begin
2 var a:= ArrGen(3, 105, i -> i + 7);
3 a.Println;
4 end.
Количество элементов, удовлетворяющих условию
Циклом
1 begin
2 var a := ArrRandom(10, -50, 50);
3 a.Println;
4 var count := 0;
5 for var i := 0 to a.Length - 1 do
6 begin
7 if a[i] > 0 then count += 1;
8 end;
9 Writeln(count);
10 end.
Методом
1 Begin
2 var a:= ArrRandom(10, -50, 50);
3 a.Println;
4 Writeln(a.Count(x -> x > 0));
5 end.
Уникальные элементы последовательности
1 Begin
2 var a:= ArrRandom(10, 0, 10);
3 a.Println;
4 a.Distinct.Println;
5 end.
Сортировка
1 Begin
2 var a:= ArrRandom(10, 0, 10);
3 a.Println;
4 a.Sorted.Println;
5 a.SortedDescending.Println;
6 end.
Последовательность в обратном порядке
1 Begin
2 var a:= ArrRandom(10, 0, 10);
3 a.Println;
4 a.Reverse.Println;
5 end.
Срезы (выделение части массива)
a[:5] – пять первых элементов массива (индексы 0..4);
a[3:] – элементы массива, начиная с a[3] и до конца;
a[2:7] – элементы массива, начиная с a[2] и заканчивая a[6];
a[::] – весь массив (эквивалентно просто a);
a[::2] – элементы массива c индексами 0, 2, 4, … (четными);
a[1::2] – элементы массива c индексами 1, 3, 5, … (нечетными);
a[4:13:3] – элементы массива с индексами 4, 7, 10;
a[13:4:-3] – элементы массива с индексами 13, 10, 7;
a[::-1] – элементы массива в обратном порядке.
Можно указывать срезы, в которых отсчет ведется от конца массива, для чего перед значением индекса ставится знак ^. При этом a[^1] – это последний элемент массива a, a[^2] предпоследний элемент и т.д. Элемента с индексом [^0] не существует!
a[^5:] – пять последних элементов массива a;
a[^1:^6:-1] – то же, но взятые в обратном порядке;
a[:^5] – все элементы массива a, кроме пяти последних
Проверка есть ли элемент в последовательности
Проверка с помощью цикла с параметром
1 Begin
2 var a:= ArrRandom(10, 0, 10);
3 a.Println;
4 var x := 5;
5 var exists := False;
6 for var i := 0 to a.Length-1 do
7 if a[i] = x then exists := True;
8 Writeln(exists);
9 end.
Проверка с помощью метода
1 Begin
2 var a:= ArrRandom(10, 0, 10);
3 a.Println;
4 var x := 5;
5 Writeln(a.Contains(x));
6 end.
Проверка есть ли в последовательности элемент удовлетворяющий условию
Проверка с помощью цикла с параметром
1 Begin
2 var a:= ArrRandom(10, -1, 10);
3 a.Println;
4 var any := false;
5 for var i := 0 to a.Length-1 do
6 begin
7 if a[i] < 0 then
8 any := true;
9 end;
10 Writeln(any);
11 end.
Проверка с помощью метода
1 Begin
2 var a:= ArrRandom(10, -1, 10);
3 a.Println;
4 Writeln(a.Any(x -> x < 0));
5 end.
Проверка все ли элементы последовательности удовлетворяют условию
Проверка с помощью цикла с параметром
1 Begin
2 var a:= ArrRandom(10, -1, 10);
3 a.Println;
4 var any := true;
5 for var i := 0 to a.Length-1 do
6 begin
7 if a[i] >= 0 then
8 any := false;
9 end;
10 Writeln(any);
11 end.
Проверка с помощью метода
1 Begin
2 var a:= ArrRandom(10, -1, 10);
3 a.Println;
4 Writeln(a.All(x -> x >= 0));
5 end.
Поиск индексов минимального или максимального элементов
Поиск индекса минимального элемента циклом
1 Begin
2 var a:= ArrRandom(10, -1, 10);
3 a.Println;
4 var min := integer.MaxValue;
5 var indexMin := -1;
6 for var i := 0 to a.Length-1 do
7 begin
8 if (a[i] < min) then
9 begin
10 min := a[i];
11 indexMin := i;
12 end;
13 end;
14 Writeln(indexMin);
15 end.
Поиск индекса минимального элемента методом
1 Begin
2 var a:= ArrRandom(10, -1, 10);
3 a.Println;
4 Writeln(a.IndexMin);
5 Writeln(a.LastIndexMin);
6 end.
Поиск индекса максимального элемента циклом
1 Begin
2 var a:= ArrRandom(10, -1, 10);
3 a.Println;
4 var max := integer.MinValue;
5 var indexMax := -1;
6 for var i := 0 to a.Length-1 do
7 begin
8 if (a[i] > max) then
9 begin
10 max := a[i];
11 indexMax := i;
12 end;
13 end;
14 Writeln(indexMax);
15 end.
Поиск индекса максимального элемента методом
1 Begin
2 var a:= ArrRandom(10, -1, 10);
3 a.Println;
4 Writeln(a.IndexMax);
5 Writeln(a.LastIndexMax);
6 end.
Пересечение (общие элементы) двух массивов
1 Begin
2 var a := ArrRandom(10, -10, 10);
3 var b := ArrRandom(10, -10, 10);
4 a.Println;
5 b.Println;
6 a.Intersect(b).Println();
7 end.
Объединение (все уникальные элементы) двух массивов
1 Begin
2 var a := ArrRandom(10, -10, 10);
3 var b := ArrRandom(10, -10, 10);
4 a.Println;
5 b.Println;
6 a.Union(b).Println();
7 end.
Разность двух массивов (элементы первого массива, которых нет во втором)
1 Begin
2 var a := ArrRandom(10, -10, 10);
3 var b := ArrRandom(10, -10, 10);
4 a.Println;
5 b.Println;
6 a.Except(b).Println();
7 end.
Объединение методов
Большинство методов для обработки последовательностей возвращает последовательность в виде результата. К ней в свою очередь можно применить те же методы, что позволяет применять несколько методов в одном вызове. Если строка вызовов становится длинной её разбивают выделяя каждый новый метод на новую строку, которая начинается с точки. Все строки, кроме первой, пишутся с отступом, чтобы показать принадлежность к одной строке кода.
Сумма положительных элементов
Например сначала можно отобрать из массива только положительные элементы, затем найти их сумму и третьим методом вывести её на экран.
1 Begin
2 var a := ArrRandom(10, -20, 20);
3 a.Println;
4 a.Where(x -> x > 0).Sum.Println;
5 end.
Квадраты элементов, которые больше 5
1 Begin
2 var a := ArrRandom(10, -20, 20);
3 a.Println;
4 a.Where(x -> x > 5)
5 .Select(x -> x * x)
6 .Println;
7 end.
Сумма индексов чётных чисел
Например, мы можем преобразовать список чисел в список пар (кортежей) чисел и их индексов (.Select((x,i) -> (x,i))). Затем пары чисел можно обрабатывать как одну переменную пары. Эта пара является кортежем. Вы можете упаковать до 7 переменных. Доступ к элементам кортежа происходит через свойства Item1, Item2 и так далее. Или вы можете распаковать кортеж в переменные с помощью слэша \ (например, \(x,i)). Тогда первая переменная будет записана в переменную x, а вторая в переменную i.
1 Begin
2 var a := ArrRandom(10, -20, 20);
3 a.Println;
4 a.Select((x,i) -> (x,i))
5 .Where(pair -> pair.Item1 mod 2 = 0)
6 .Select(\(x,i) -> i)
7 .Sum.Println;
8 end.