78.49K
Категория: ПрограммированиеПрограммирование

Обобщённые типы и ограничения

1.

Дисциплина «Программирование»
В.В. Подбельский, В.А. Дударев, О.В. Максименкова
Модуль 3, практическое занятие 8
Обобщённые типы и ограничения

2.

Задача 1. Класс с двумя обобщёнными параметрами
• Описать обобщённый класс TwoSequences<T, V>, T и V
ограничены типами значений. В классе определить:
• Автореализуемые свойства доступа к двум массивам (типа T и
типа V)
• Конструктор с двумя параметрами массивами типов T и V. Если
в качестве одного из параметров передана пустая ссылка –
конструктор порождает исключение типа
ArgumentNullException
Для тестирования класса используйте код со следующего слайда
2

3.

Задача 1. Класс с двумя обобщёнными параметрами
public class A
{
int a;
public int AA { get { return a; } set { a = value; } }
public A(int x) { AA = x; }
}
double[] da = { 1.0, 1.3, 2.2, 3.3 };
A[] arr1 = { new A(5), new A(7) };
TwoSequences<A, double> ts = new TwoSequences<A, double>(arr1, da);
try { ts.SecondSequence[4] = 4.4; }
catch (IndexOutOfRangeException e) { Console.WriteLine("Индекс отсутствует");
}
try { TwoSequences<A, double> ts1 = new TwoSequences<A, double>(arr1, null);
}
3
catch (ArgumentOutOfRangeException ex) { Console.WriteLine("ссылка null"); }

4.

Задание 2. Обобщённое гадание
Реализуйте гадание на основе перечислений. Пользователь вводит свой вопрос и
получает один из заготовленных с перечислении вариантов ответа.
Условие задачи: Создайте перечисление с возможными вариантами ответа
(Yes/No/Maybe и т.д.). Реализуйте метод, который будет выбирать случайный элемент
перечисления и возвращать его.
Подсказки:
• Enum.GetNames(yourEnum.GetType()).Length) - количество элементов в перечислении
Enum.GetName(yourEnum.GetType(), number) - получение объекта из перечисления по
значению.
• YourMethod(new yourEnum()); - вызов метода с перечислением
Дополнительно:
• Добавьте возможность выбрать набор вариантов ответа сразу после ввода вопроса;
• Придумайте смешной набор вариантов ответа;
• Вместо обычного гадания сделайте таро (и всю колоду в виде перечисления)
Используйте заготовку кода со следующего слайда.
4

5.

Задание 2. Обобщённое гадание
class Program
{
// TODO: define some enum
private static T GetAnswer<T>(T answers) where T : Enum
{
throw new NotImplementedException();
}
static void Main(string[] args)
{
string question = "Type your question here...";
Console.WriteLine(question);
// Console.WriteLine(GetAnswer(...));
}
}
5

6.

Задача 3. Обобщённый интерфейс шифрования
Дан обобщенный интерфейс, описывающий классы, которые умеют кодировать и декодировать
информацию.
public interface IEncrypted<T, TU>
{
T Encode(TU u);
TU Decode(T t);
}
Необходимо написать классы, реализующие данный интерфейс.
• Первый класс Caesar – конкретный класс, реализация алгоритма шифрования Цезаря
(https://en.wikipedia.org/wiki/Caesar_cipher) с неотрицательным ключом.
• Второй класс WindEncoder кодирует 8 направлений ветра с помощью равномерного кодирования.
• Третий класс SideOfTheWorldEncoder кодирует 4 стороны света с помощью равномерного
кодирования.
В основной программе (консольном приложении) протестируйте решение.
Для вызова методов второго и третьего классов используйте массив объектов, реализующих
обобщенный интерфейс.
6

7.

Задача 3. Обобщённый интерфейс шифрования
public abstract class BinaryToStringEncoder : IEncrypted<byte[], string>
{
protected abstract Dictionary<string, byte[]> GetDictionary();
public byte[] Encode(string u)
{
// TODO: реализовать данный метод
throw new NotImplementedException();
// return GetDictionary().
}
public string Decode(byte[] t)
{
// TODO: реализовать данный метод
throw new NotImplementedException();
// return GetDictionary().
}
}
7

8.

Задача 3. Обобщённый интерфейс шифрования
public class SideOfTheWorldEncoder : BinaryToStringEncoder
{
protected override Dictionary<string, byte[]> GetDictionary()
{
return new Dictionary<string, byte[]>
{
{ "С", new byte[] { 0, 0 } },
{ "Ю", new byte[] { 1, 0 } },
{ "З", new byte[] { 1, 1 } },
{ "В", new byte[] { 0, 1 } }
};
}
8

9.

Задача 3. Обобщённый интерфейс
// алгоритм равномерного кодирования 8-ми направлений ветра:
// С, Ю, З, В, СЗ, СВ, ЮЗ, ЮВ.
public class WindEncoder : BinaryToStringEncoder
{
protected override Dictionary<string, byte[]> GetDictionary()
{
return new Dictionary<string, byte[]>
{
{ "С", new byte[] { 0, 0, 0 } },
{ "Ю", new byte[] { 1, 0, 0 } },
{ "З", new byte[] { 1, 1, 0 } },
{ "В", new byte[] { 0, 1, 0 } },
{ "СЗ", new byte[] { 1, 1, 1 } },
{ "СВ", new byte[] { 0, 0, 1 } },
{ "ЮЗ", new byte[] { 1, 0, 1 } },
{ "ЮВ", new byte[] { 0, 1, 1 } }
};
}
}
9

10.

Задача 4. Обобщённая очередь
Определить пользовательский класс, реализующий очередь (организованную по принципу
FIFO), способную оперировать данными любых типов.
Члены класса:
• Свойство First – ссылка на первый элемент очереди;
• Свойство Last – ссылка на последний элемент очереди;
• Свойство Capacity – ёмкость очереди;
• Свойство IsEmpty возвращает true, если очередь пуста и false если в очереди есть хотя
бы один элемент;
• Свойство IsFull возвращает true, если ёмкость очереди исчерпана, false – в противном
случае;
• Метод Enqueue() помещает объект в очередь;
• Метод Dequeue() удаляет объект из очереди.
Подготовить демо-проект консольного приложения, позволяющий работать с разработанной
очередью и демонстрирующий все её возможности.
10

11.

Задача 5. Обобщённое бинарное дерево
Создать обобщенный класс бинарного дерева.
Подсказка: для управления узлами дерева потребуются сравнения их друг с другом.
Дерево состоит из узлов (отдельный класс) и связей между ними (ссылки на объекты). В бинарном
дереве у узла могут быть только две связи, адресующие – правый и левый узлы-потомки. Если у
узла нет связей с потомками – это лист дерева. Каждый узел может быть либо корнем поддерева,
либо листом дерева. Первый узел называют корнем дерева.
11

12.

Задача 5. Обобщённое бинарное дерево
Для построения дерева будут использовать два обобщенных класса:
класс BinaryTree<ElemType> содержит в качестве поля ссылку на корень дерева. Методы: конструктор без
параметров; метод Insert() для добавления в дерево нового значения; метод Preorder() выполняющий
вывод в порядке слева направо значений из узлов, начиная с заданного; метод ToString() для
формирования строки с узлами дерева и свойство IsEmpty для проверки пустоты дерева.
Класс BTnode<ValType> - узел дерева, где находится сохраняемое значение, счетчик количеств этих
значений и две (правая и левая) связи узла – ссылки на объекты класса BTnode<ValType>. Конструктор
класса добавляет в дерево один лист, то есть создает узел с заданным значением и пустыми ссылками.
Метод InsertValue() добавляет значение в дерево. Новый узел создается в том случае, когда в дереве это
значение отсутствует.
В интерфейс класса BinaryTree<> включить следующие возможности:
• удаление элемента из дерева (реализовать метод Delete);
• поиск элемента в дереве (реализовать метод Find);
• очистка всех элементов дерева (реализовать метод Clear);
• печатать дерево справа налево (реализовать метод Inorder);
• печатать дерево симметрично (реализовать метод Postorder).
12
English     Русский Правила