Advertisement
multifacs

test final

Dec 6th, 2024 (edited)
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.39 KB | Source Code | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. // Интерфейс стратегии вычисления, определяющий метод для расчета следующего элемента последовательности
  6. public interface ICalculationStrategy
  7. {
  8.     int Calculate(int prev1, int prev2);  // prev1 - предыдущий элемент, prev2 - пред-предыдущий элемент
  9. }
  10.  
  11. // Конкретная реализация стратегии: вычисляет квадрат разности двух предыдущих элементов
  12. public class SquareDifferenceStrategy : ICalculationStrategy
  13. {
  14.     public int Calculate(int prev1, int prev2)
  15.     {
  16.         return (prev1 - prev2) * (prev1 - prev2);  // (xi-1 - xi-2)^2
  17.     }
  18. }
  19.  
  20. // Декоратор стратегии: оборачивает существующую стратегию и меняет знак результата на противоположный
  21. public class NegativeDecorator : ICalculationStrategy
  22. {
  23.     private readonly ICalculationStrategy _strategy;  // Хранит ссылку на декорируемую стратегию
  24.  
  25.     public NegativeDecorator(ICalculationStrategy strategy)
  26.     {
  27.         _strategy = strategy;
  28.     }
  29.  
  30.     public int Calculate(int prev1, int prev2)
  31.     {
  32.         return -_strategy.Calculate(prev1, prev2);  // Инвертируем результат базовой стратегии
  33.     }
  34. }
  35.  
  36. // Основной класс последовательности, реализующий интерфейс IEnumerable для возможности перебора элементов
  37. public class Sequence : IEnumerable<int>
  38. {
  39.     private readonly int _x0;  // Первый элемент последовательности
  40.     private readonly int _x1;  // Второй элемент последовательности
  41.     private readonly int _n;   // Количество элементов для генерации
  42.     private readonly ICalculationStrategy _strategy;  // Стратегия вычисления элементов
  43.  
  44.     public Sequence(int x0, int x1, int n, ICalculationStrategy strategy)
  45.     {
  46.         _x0 = x0;
  47.         _x1 = x1;
  48.         _n = n;
  49.         _strategy = strategy;
  50.     }
  51.  
  52.     // Возвращает итератор для перебора элементов последовательности
  53.     public IEnumerator<int> GetEnumerator()
  54.     {
  55.         return new SequenceIterator(_x0, _x1, _n, _strategy);
  56.     }
  57.  
  58.     // Реализация необобщенного интерфейса IEnumerable
  59.     IEnumerator IEnumerable.GetEnumerator()
  60.     {
  61.         return GetEnumerator();
  62.     }
  63. }
  64.  
  65. // Итератор последовательности, реализующий логику перебора элементов
  66. public class SequenceIterator : IEnumerator<int>
  67. {
  68.     private readonly int _x0;  // Первый элемент
  69.     private readonly int _x1;  // Второй элемент
  70.     private readonly int _n;   // Количество элементов
  71.     private readonly ICalculationStrategy _strategy;  // Стратегия вычисления
  72.     private int _position;     // Текущая позиция в последовательности
  73.     private int _current;      // Текущий элемент
  74.     private int _prev1;        // Предыдущий элемент
  75.     private int _prev2;        // Пред-предыдущий элемент
  76.  
  77.     public SequenceIterator(int x0, int x1, int n, ICalculationStrategy strategy)
  78.     {
  79.         _x0 = x0;
  80.         _x1 = x1;
  81.         _n = n;
  82.         _strategy = strategy;
  83.         Reset();  // Инициализация начального состояния
  84.     }
  85.  
  86.     // Переход к следующему элементу последовательности
  87.     public bool MoveNext()
  88.     {
  89.         // Проверяем, не достигли ли мы конца последовательности
  90.         if (_position >= _n)
  91.             return false;
  92.  
  93.         // Определяем текущий элемент в зависимости от позиции
  94.         if (_position == 0)
  95.         {
  96.             _current = _x0;  // Первый элемент
  97.         }
  98.         else if (_position == 1)
  99.         {
  100.             _current = _x1;  // Второй элемент
  101.         }
  102.         else
  103.         {
  104.             // Вычисляем следующий элемент с помощью выбранной стратегии
  105.             _current = _strategy.Calculate(_prev1, _prev2);
  106.         }
  107.  
  108.         // Обновляем предыдущие значения для следующей итерации
  109.         _prev2 = _prev1;
  110.         _prev1 = _current;
  111.         _position++;
  112.         return true;
  113.     }
  114.  
  115.     // Сброс итератора в начальное состояние
  116.     public void Reset()
  117.     {
  118.         _position = 0;
  119.         _current = 0;
  120.         _prev1 = _x1;
  121.         _prev2 = _x0;
  122.     }
  123.  
  124.     // Текущий элемент последовательности
  125.     public int Current => _current;
  126.  
  127.     // Реализация необобщенного интерфейса IEnumerator
  128.     object IEnumerator.Current => Current;
  129.  
  130.     // Освобождение ресурсов (в данном случае не требуется)
  131.     public void Dispose() { }
  132. }
  133.  
  134. // Дополнительная стратегия: суммирует два предыдущих элемента
  135. public class SumStrategy : ICalculationStrategy
  136. {
  137.     public int Calculate(int prev1, int prev2)
  138.     {
  139.         return prev1 + prev2;  // Числа Фибоначчи
  140.     }
  141. }
  142.  
  143. // Дополнительный декоратор: умножает результат на 2
  144. public class MultiplyByTwoDecorator : ICalculationStrategy
  145. {
  146.     private readonly ICalculationStrategy _strategy;
  147.  
  148.     public MultiplyByTwoDecorator(ICalculationStrategy strategy)
  149.     {
  150.         _strategy = strategy;
  151.     }
  152.  
  153.     public int Calculate(int prev1, int prev2)
  154.     {
  155.         return 2 * _strategy.Calculate(prev1, prev2);
  156.     }
  157. }
  158.  
  159. class Program
  160. {
  161.     static void Main()
  162.     {
  163.         // Демонстрация базовой последовательности
  164.         Console.WriteLine("Original sequence:");
  165.         var sequence = new Sequence(0, 2, 10, new SquareDifferenceStrategy());
  166.         foreach (var number in sequence)
  167.         {
  168.             Console.Write($"{number} ");
  169.         }
  170.         Console.WriteLine();
  171.  
  172.         // Демонстрация последовательности с декоратором, меняющим знак
  173.         Console.WriteLine("\nSequence with negative decorator:");
  174.         var decoratedSequence = new Sequence(0, 2, 10,
  175.             new NegativeDecorator(new SquareDifferenceStrategy()));
  176.         foreach (var number in decoratedSequence)
  177.         {
  178.             Console.Write($"{number} ");
  179.         }
  180.         Console.WriteLine();
  181.  
  182.         // Демонстрация последовательности с комбинацией декораторов
  183.         Console.WriteLine("\nSequence with multiple decorators:");
  184.         var complexSequence = new Sequence(0, 2, 10,
  185.             new MultiplyByTwoDecorator(
  186.                 new NegativeDecorator(
  187.                     new SquareDifferenceStrategy())));
  188.         foreach (var number in complexSequence)
  189.         {
  190.             Console.Write($"{number} ");
  191.         }
  192.         Console.WriteLine();
  193.     }
  194. }
  195.  
  196. // Этот код полностью реализует обе задачи. Давайте разберем основные компоненты:
  197.  
  198. // ICalculationStrategy - интерфейс для стратегии вычисления элементов последовательности.
  199. // SquareDifferenceStrategy - конкретная реализация стратегии, вычисляющая квадрат разности двух предыдущих элементов.
  200. // NegativeDecorator - декоратор стратегии, который меняет знак результата на противоположный.
  201. // Sequence - основной класс последовательности, реализующий IEnumerable<int>.
  202. // SequenceIterator - итератор последовательности, реализующий IEnumerator<int>.
  203.  
  204. // Преимущества данной реализации:
  205.  
  206. // Использование паттерна Стратегия позволяет легко менять способ вычисления элементов последовательности.
  207. // Паттерн Декоратор дает возможность динамически добавлять новое поведение к существующим стратегиям.
  208. // Использование итератора обеспечивает эффективный доступ к элементам последовательности без необходимости хранить все элементы в памяти.
  209. // Код легко расширяем - можно добавлять новые стратегии и декораторы без изменения существующего кода.
  210. // Можно добавить дополнительные стратегии или декораторы. Например:
  211.  
  212. // Дополнительная стратегия
  213. public class SumStrategy : ICalculationStrategy
  214. {
  215.     public int Calculate(int prev1, int prev2)
  216.     {
  217.         return prev1 + prev2;
  218.     }
  219. }
  220.  
  221. // Дополнительный декоратор
  222. public class MultiplyByTwoDecorator : ICalculationStrategy
  223. {
  224.     private readonly ICalculationStrategy _strategy;
  225.  
  226.     public MultiplyByTwoDecorator(ICalculationStrategy strategy)
  227.     {
  228.         _strategy = strategy;
  229.     }
  230.  
  231.     public int Calculate(int prev1, int prev2)
  232.     {
  233.         return 2 * _strategy.Calculate(prev1, prev2);
  234.     }
  235. }
  236.  
  237. // И использовать их так:
  238.  
  239.  
  240. // Комбинирование декораторов
  241. var complexSequence = new Sequence(0, 2, 10,
  242.     new MultiplyByTwoDecorator(
  243.         new NegativeDecorator(
  244.             new SquareDifferenceStrategy())));
  245. // Это демонстрирует гибкость и расширяемость решения.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement