Книга программиста/Применение LINQ на практике
К оглавлению | Назад | Вперёд
Все программы, код которых выложен здесь, являются работоспособными. На момент написания программ использовалась среда PascalABC.Net 3.0.
Поэлементные операции, агрегирование и генерирование последовательностей
[править]Первый положительный и последний отрицательный элементы
[править]Дана целочисленная последовательность, содержащая как положительные, так и отрицательные числа. Вывести ее первый положительный элемент и последний отрицательный элемент.
begin
var A := ReadArrInteger(5);
WritelnFormat('{0} {1}', A.First(x -> x > 0), A.Last(x -> x < 0));
end.
Число, которое оканчивается на символ D
[править]Дана цифра D (однозначное целое число) и целочисленная последовательность A. Вывести первый положительный элемент последовательности A, оканчивающийся цифрой D. Если требуемых элементов в последовательности A нет, то вывести 0.
begin
var D := ReadlnInteger('D:');
Writeln(ReadArrInteger(ReadlnInteger('N:')).First(x -> (x > 0) and (x mod 10 = D)));
end.
Последняя строка из массива строк
[править]Дано целое число L (> 0) и строковая последовательность A. Вывести последнюю строку из A, начинающуюся с цифры и имеющую длину L. Если требуемых строк в последовательности A нет, то вывести строку «Not found».
begin
var L := ReadlnInteger('L:');
var S := ReadArrString(ReadlnInteger('N:')).LastOrDefault(x -> (x.Chars[1] in ['0'..'9']) and (Length(x) = L));
Writeln(S = nil ? 'Not found' : S);
end.
Единственный элемент
[править]Дан символ С и строковая последовательность A. Если A содержит единственный элемент, оканчивающийся символом C, то вывести этот элемент; если требуемых строк в A нет, то вывести пустую строку; если требуемых строк больше одной, то вывести строку «Error».
var
S: string;
begin
var C := ReadlnChar('C:');
try
S := ReadArrString(ReadlnInteger('N:')).Single(x -> x.Chars[Length(x)] = C);
except
on System.InvalidOperationException do Writeln('Error'); end;
if S <> '' then Writeln(S);
end.
Строки большие по длине одного символа
[править]Дан символ С и строковая последовательность A. Найти количество элементов A, которые содержат более одного символа и при этом начинаются и оканчиваются символом C.
begin
var C := ReadlnChar('C:');
Writeln(ReadArrString(ReadlnInteger('N:')).Count(x -> (x.Chars[1] = C) and (x.Chars[Length(x)] = C) and (Length(x) > 1)));
end.
Сумма длин всех строк
[править]Дана строковая последовательность. Найти сумму длин всех строк, входящих в данную последовательность.
begin
Writeln(ReadArrString(ReadlnInteger('N:')).Sum(x -> x.Length));
end.
Отрицательные элементы
[править]Дана целочисленная последовательность. Найти количество ее отрицательных элементов, а также их сумму. Если отрицательные элементы отсутствуют, то дважды вывести 0.
begin
var A := ReadArrInteger(ReadlnInteger('N:')).Where(x -> x < 0);
WritelnFormat('{0} {1}', A.Count(), A.Sum());
end.
Положительные элементы
[править]Дана целочисленная последовательность. Найти количество ее положительных двузначных элементов, а также их среднее арифметическое (как вещественное число). Если требуемые элементы отсутствуют, то дважды вывести 0 (первый раз как целое, второй — как вещественное).
Описание алгоритма |
---|
|
begin
var A := ReadArrInteger(ReadlnInteger('N:')).Where(x -> (x > 9) and (x < 100));
WritelnFormat('{0} {1}', A.Count(), A.Count() > 0 ? A.Average() : 0);
end.
Минимальный положительный элемент
[править]Дана целочисленная последовательность. Вывести ее минимальный положительный элемент или число 0, если последовательность не содержит положительных элементов.
begin
var A := ReadArrInteger(ReadlnInteger('N:')).Where(x -> x > 0);
Writeln(A.Count() > 0 ? A.Min() : 0);
end.
Упорядоченные строки
[править]Дано целое число L (> 0) и строковая последовательность A. Строки последовательности A содержат только заглавные буквы латинского алфавита. Среди всех строк из A, имеющих длину L, найти наибольшую (в смысле лексикографического порядка). Вывести эту строку или пустую строку, если последовательность не содержит строк длины L.
begin
var L := ReadlnInteger();
var A := ReadArrString(ReadlnInteger('N:')).Where(x -> x.Length = L);
Writeln(A.Count() > 0 ? A.SortedDescending().First() : '');
end.
Первые символы строк
[править]Дана последовательность непустых строк. Используя метод Aggregate, получить строку, состоящую из начальных символов всех строк исходной последовательности.
Описание алгоритма |
---|
|
begin
ReadArrString(ReadlnInteger('N:')).Select(x -> x.Chars[1] + '').Aggregate((a, b) -> a + b).JoinIntoString('').Println();
end.
begin
Writeln(ReadArrString(ReadlnInteger('N:')).Sum(x -> x.Chars[1]));
end.
Произведение цифр
[править]Дана целочисленная последовательность. Используя метод Aggregate, найти произведение последних цифр всех элементов последовательности. Чтобы избежать целочисленного переполнения, при вычислении произведения использовать вещественный числовой тип.
begin
Writeln(ReadArrInteger(ReadlnInteger('N:')).Select(x -> x mod 10).Aggregate(1.0, (a, b) -> a * b));
end.
Сумма дробей
[править]Дано целое число N (> 0). Используя методы Range и Sum, найти сумму 1 + (1/2) + … + (1/N) (как вещественное число).
begin
Writeln(Range(1, ReadlnInteger('N:')).Sum(x -> 1 / x));
end.
begin
Writeln(ReadlnInteger('N:').Range().Sum(x -> 1 / x));
end.
Факториал
[править]Дано целое число N (0 ≤ N ≤ 15). Используя методы Range и Aggregate, найти факториал числа N: N! = 1·2·…·N при N ≥ 1; 0! = 1. Чтобы избежать целочисленного переполнения, при вычислении факториала использовать вещественный числовой тип.
begin
Writeln(Range(1, ReadlnInteger('X:')).Aggregate(1.0, (a, b)-> a * b));
end.
Среднее арифметическое
[править]Даны целые числа A и B (A < B). Используя методы Range и Average, найти среднее арифметическое квадратов всех целых чисел от A до B включительно: (A2 + (A+1)2 + … + B2)/(B − A + 1) (как вещественное число).
begin
Range(ReadlnInteger('A:'), ReadlnInteger('B:')).Select(x -> Sqr(x)).Average();
end.
Фильтрация, сортировка, теоретико-множественные операции
[править]Положительные элементы
[править]Дана целочисленная последовательность. Извлечь из нее все положительные числа, сохранив их исходный порядок следования.
begin
ReadArrInteger(ReadlnInteger('N:')).Where(x -> x > 0).Println();
end.
Повторяющиеся элементы
[править]Дана целочисленная последовательность. Извлечь из нее все нечетные числа, сохранив их исходный порядок следования и удалив все вхождения повторяющихся элементов, кроме первых.
begin
ReadArrInteger(ReadlnInteger('N:')).Where(x -> x mod 2 <> 0).Distinct().Println();
end.
Последние повторения элементов
[править]Дана цифра D (целое однозначное число) и целочисленная последовательность A. Извлечь из A все различные положительные числа, оканчивающиеся цифрой D (в исходном порядке). При наличии повторяющихся элементов удалять все их вхождения, кроме последних.
begin
var D := ReadlnInteger('D:');
ReadArrInteger(ReadlnInteger('N:')).Where(x -> x mod 10 = D).Reverse().Distinct().Reverse().Println();
end.
Средняя сложность
[править]Задача о веществах
[править]Есть файл, в котором вещества описаны в следующем формате (каждое вещество на одной строке): название масса тип. Вывести в новый файл описания тех веществ, которые весят больше 24 и являются диэлектриками.
const
Path1 = 'C:\Ilya\AlgoРитмы\Файл1.txt';
Path2 = 'C:\Ilya\AlgoРитмы\Файл2.txt';
type
Substance = record
Name: string;
Mass: real;
T: string;
constructor (n: string; m: real; st: string);
begin
Name := n;
Mass := m;
T := st;
end;
end;
var
Substances: List<Substance>;
begin
var A := ReadAllLines(Path1);
Substances := new List<Substance>();
for var i := 0 to A.Length - 1 do
begin
var words := A[i].ToWords();
var n := words.Length - 1;
Substances.Add(new Substance(words.SkipLast(2).JoinIntoString(' '), StrToFloat(words[n - 1]), words[n]));
end;
WriteAllLines(Path2, Substances.FindAll(x -> (x.Mass > 24) and (x.T = 'диэлектрик')).ToArray().ConvertAll(x -> Format('{0} {1} {2}', x.Name, x.Mass, x.T)));
Readln();
end.
Столбцы максимумов
[править]begin
Print(MatrRandom(5, 5, 0, 10).Cols().Select(x -> x.Max()));
end.
Дополнительные примеры
[править]Сумма элементов
[править]begin
Print(Arr(1, 2, 3, 4, 5, 6, 7).Sum());
end.
Элементы большие 10
[править]begin
Writeln(Arr(4, 6, 12, 17, 9, 8).Where(x -> x > 10).Count());
end.
Переворот чисел
[править]begin
Writeln(Arr(544, 62, 152, 171, 59, 18).Select(x -> StrToInt(IntToStr(x).Reverse().JoinIntoString())));
end.
Числа в диапазоне [A, B], кратные 7
[править]begin
WritelnFormat('Количество чисел, которые делятся на 7 равно = {0}.', Range(ReadlnInteger('A:'), ReadlnInteger('B:')).Where(x -> x mod 7 = 0).Count());
end.
Первый нечётный элемент массива
[править]begin
var Outcome := ReadArrInteger(5).ToList().Find(x -> x mod 2 <> 0);
WritelnFormat('Первый нечётный элемент массива = {0}.', Outcome = 0 ? 'элемента не найдено' : IntToStr(Outcome));
end.
Числа
[править]begin
var X := ReadlnInteger();
var D := ReadlnInteger();
var A := ReadArrInteger(ReadlnInteger('Размер массива:'));
WritelnFormat('Произведение чисел, больших D и стоящих на местах, кратных 3, = {0}.', A.Where((x, i)-> (x > D) and (i mod 3 = 0)).Aggregate((x, y) -> x * y));
WritelnFormat('Количество чисел, неравных заданному Х равно {0}.', A.Where(y -> y <> X).Count());
end.