Книга программиста/Применение 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.