Лабораторная работа №4. Последовательности.

Генерация последовательностей, оператор yield return

Последовательность - любая коллекция, реализующая интерфейс IEnumerable<T>.
Ключевое слово yield позволяет заполнить последовательность объектами.
Пример: следующий метод создаёт последовательность из n целых чисел.
static IEnumerable<int> GenerateIntegerNumbers(int first, int n) {
	for (int i = 0; i < n; i++)
	{
		yield return first + i;
	}
} 
Результат работы метода можно сохранить в переменной
IEnumerable<int> seq = GenerateIntegerNumbers(0, 10);
или
var seq = GenerateIntegerNumbers(0, 10);
Для того, чтобы перебрать элементы коллекции, используем цикл foreach:
foreach (var item in seq)
{
	Console.Write($"{item} ");
}
Последовательность может быть бесконечной. В следующем примере генерируется бесконечная последовательность чисел Фибоначчи.
        static IEnumerable<int> Fibonacci()
        {
            int a = 1;
            int b = 1;
            for (;;)
            {
                yield return a;
                var c = a + b;
                a = b;
                b = c;
            }
        }
Элементы последовательности можно просмотреть так:
           foreach (var item in Fibonacci().Take(15))
            {
                Console.Write($"{item} ");
            }
Метод Take выбирает определенное количество элементов. Если элементы выбираются не с первого, используется Skip.
Также для генерации последовательности можно использовать метод 
public static IEnumerable<int> Range( 
        int start, 
        int count);
Пример использования:
IEnumerable<int> seq = Enumerable.Range(1, 100);
Операция Repeat генерирует последовательность, повторяя указанный элемент заданное количество раз.
IEnumerable<int> seq = Enumerable.Repeat(2, 10);

Задачи на генерацию последовательностей

  1. Создайте метод расширения
    static void PrintSequence<T>(this IEnumerable<T> seq, string delimiter = ", ")
    
    выводящий на консоль все элементы последовательности
  2. Создайте метод
    static IEnumerable<int> GenerateRandomSequence(int n, int min = -100, int max = 100)
    
    генерирующий последовательность из n случайных чисел в промежутке от min до max.
  3. Создайте последовательность из N четных чисел, начиная с 0.
  4. Создайте последовательность 2017 2012 2007 2002 1997 1992 1987 1982 1977 1972
  5. Создайте последовательность из N целых чисел, заданных итерационным процессом: \( a_1=1,\,a_2=2,\,a_k=a_{k-2}+2a_{k-1} \)
  6. Создайте последовательность из N вещественных чисел, заданных итерационным процессом: \( a_1=1,\,a_2=2,\,a_k=(a_{k-2}+2a_{k-1})/3 \)
  7. Создайте следующий метод, генерирующий последовательность
    static IEnumerable<T> Generate<T>(int n, T first, T second, Func<T, T, T> function)
    
    Func<in T1, in T2, out TResult> - тип делегата для вызова метода с двумя параметрами типов T1 и Т2, возвращающий TResult. Сгенерируйте с помощью метода последовательность Фибоначчи. Примените его для решения двух предыдущих задач. В качестве последнего аргумента используем лямбда-выражения.
  8. Создать метод
    static IEnumerable<T> Cycle<T>(params T[] array)
    
    создающий бесконечную последовательность, в которой раз за разом повторяются элементы массива.
  9. Создать метод
    static IEnumerable<double> DoubleRange(double min, double max, double step)
    
    создающий последовательность из вещественных чисел, расположенных на интервале [min, max] с интервалом step
  10. Создать последовательность, состоящую из приближенных значений квадратного корня заданного числа x, найденных по формуле \[ a_k=\frac{1}{2}\left(a_{k-1}+\frac{x}{a_{k-1}}\right) \]

Методы расширения последовательностей

  1. Дана целочисленная последовательность, содержащая как положительные, так и отрицательные числа. Вывести ее первый положительный элемент и последний отрицательный элемент.
    Указание Используем методы First и Last. В качестве параметров используем лямбда-выражения.
  2. Дана цифра D (однозначное целое число) и целочисленная последовательность A. Вывести первый положительный элемент последовательности A, оканчивающийся цифрой D. Если требуемых элементов в последовательности A нет, то вывести 0.
    Указание Используем метод FirstOrDefault.
    Указание Для проверки D на то, что он является цифрой, используем Debug.Assert.
  3. Дан символ С и строковая последовательность A. Если A содержит единственный элемент, оканчивающийся символом C, то вывести этот элемент; если требуемых строк в A нет, то вывести пустую строку; если требуемых строк больше одной, то вывести строку «Error».
    Указание Используем метод SingleOrDefault.
    Указание Также удобно использовать операцию ??
  4. Дан символ С и строковая последовательность A. Найти количество элементов A, которые содержат более одного символа и при этом начинаются и оканчиваются символом C.
    Указание Используем метод Count.
    Указание Для определения длины строки используем свойство Length. Доступ к элементу строки - по индексу. Индексация начинается с нуля.
  5. Дана строковая последовательность. Найти сумму длин всех строк, входящих в данную последовательность.
    Указание Используем метод Sum.
  6. Дано целое число N (> 0). Используя методы Range, Select и Sum, найти сумму 1 + (1/2) + … + (1/N) (как вещественное число).
  7. Дана целочисленная последовательность. Извлечь из нее все положительные числа, сохранив их исходный порядок следования. (Используем Where)
  8. Дана целочисленная последовательность. Извлечь из нее все нечетные числа, сохранив их исходный порядок следования и удалив все  вхождения повторяющихся элементов, кроме первых. (Используем Distinct)
  9. Даны целые числа K1 и K2 и целочисленная последовательность A; 1 ≤ K1 < K2 ≤ N, где N — размер последовательности A. Найти сумму положительных элементов последовательности с порядковыми номерами от K1 до K2 включительно. (Используем Skip, Take)
  10. Дана целочисленная последовательность. Обрабатывая только положительные числа, получить последовательность их последних цифр и удалить в полученной последовательности все вхождения одинаковых цифр, кроме первого. Порядок полученных цифр должен соответствовать порядку исходных чисел. (Where, Select, Distinct)