Книга программиста/Применение 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 (первый раз как целое, второй — как вещественное).

Описание алгоритма
  1. Получить все положительные двузначные числа.
  2. Вывести 0, если их нет, и вывести их среднее арифметическое, если их количество больше 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, получить строку, состоящую из начальных символов всех строк исходной последовательности.

Описание алгоритма
  1. Получить все первые символы строк.
  2. Сложить, используя метод Aggregate.
  3. Склеить в строку.
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.