Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 36

МІНІСТЕРСТВО ОСВІТИ ТА НАУКИ УКРАЇНИ

НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ


«ХАРКІВСЬКИЙ ПОЛІТЕХНІЧНИЙ ІНСТИТУТ»
Кафедра програмної інженерії та інформаційних технологій управління

ЗВІТ
по лабораторній роботі №3
з дисципліни «Об'єктно-орієнтоване програмування. Ознайомча
практика»

Виконав:
ст. гр. КН-
222в Єсипенко
Є. С.

Перевірив:
асист. Ковальчук Д.

Харків 2023
Тема: Узагальнене програмування.

Мета роботи: Метою даної роботи є вивчення концепції узагальненого


програмування (generics) в мові C# та її практичне застосування.

Завдання:

1. Індивідуальне завдання
Розширити програму, яка була створена у попередній лабораторній роботі,
ієрархією сутностей відповідно до наведеної таблиці:

Варіант:

Клас-сутність Перша ознака Друга ознака


сортування сортування

Альбом За алфавітом назви За роком створення

Реалізувати функції збереження даних у XML-форматі та завантаження


даних з XML-документу. Для роботи з XML-документами
використовувати серіалізацію та десеріалізацію. Для зберігання сутностей
у групі замість масиву використати список. Відтворити завдання
попередніх лабораторних робіт.
Усі класи, крім класу який містить функцію Main(), розташувати в окремій
бібліотеці. В консольному застосунку підключити створену бібліотеку та
здійснити тестування всіх функцій. Реалізувати тестування трьох
варіантів:
● з представленням додаткових даних у вигляді рядку
● з застосуванням спеціальної структури
● з застосуванням окремо створеного класу.
Передбачити перехоплення можливих винятків.

Program.cs
using CreativeTeamLib;
using System;

namespace BookshelfApp
{
class Program
{
static void Main(string[] args)
{
// Створюємо порожню полицю:
CreativeTeam<Country> bookshelf = new();

// Додаємо книжки
bookshelf += new Album<Country>("Nirvana", 1999,
new Country() {});

bookshelf += new Album<Country>("Arctic Monkeys", 2015,


new Country() {});

bookshelf += new Album<Country>("AC/DC", 1999,


new Country() {});

// Шукаємо книжки з певною послідовністю


літер: Console.WriteLine("Уведiть послiдовнiсть
лiтер:"); string sequence = Console.ReadLine() ??
"";
/*Console.WriteLine("Type the letters of the street:");

string sequence1 = Console.ReadLine() ?? "";*/

CreativeTeam<Country> newBookshelf = new()


{
arraysOfSongs =
bookshelf.ContainsCharacters(sequence)
};

// Виводимо результат на екран:


Console.WriteLine("Знайденi пісні:");
Console.WriteLine(newBookshelf);
Console.WriteLine();
//Console.WriteLine(newGroup);

try
{
// Зберігаємо дані про книжки:
bookshelf.WriteAlbums("Bookshelf.xml");

// Здійснюємо сортування за назвами та зберігаємо у файлі:


bookshelf.SortByTitle();
Console.WriteLine("За назвами:");
Console.WriteLine(bookshelf);
Console.WriteLine();
bookshelf.WriteAlbums("ByTitle.xml");

// Здійснюємо сортування за кількістю авторів та зберігаємо у


файлі:
bookshelf.SortByYear();
Console.WriteLine("За роками:");
Console.WriteLine(bookshelf);
Console.WriteLine();
bookshelf.WriteAlbums("ByAuthorsCount.xml");
bookshelf.ReadAlbums("ByTitle.xml");
}
catch (Exception ex)
{
Console.WriteLine("------------Виняток------------");
Console.WriteLine(ex.GetType());
Console.WriteLine("-------------Змiст
----------------------------------------------------------")
;
Console.WriteLine(ex.Message);
Console.WriteLine("-------Трасування стеку
--------------------------------------------------------------")
;
Console.WriteLine(ex.StackTrace);
}
}
}
}

CreativeTeamLib.cs
using System;
using System.Collections.Generic;
using System.Collections;
using System.Xml.Serialization;
using System.IO;
namespace CreativeTeamLib
{
// Структура для опису
автора public class Country
{

[System.Xml.Serialization.XmlAttributeAttribute()]
public string NameOfCountry { get; set; }
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Title { get; set; }
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Year { get; set; }

public Country(string nameOfCountry)


{
this.NameOfCountry = nameOfCountry;
}

public Country()
{

// Перевизначення еквівалентності
public override bool Equals(object? obj)
{
if (obj == null)
{
return false;
}
Country author = (Country)obj;
return author.NameOfCountry == NameOfCountry; // && author.Name
== Name;
}

// Визначення представлення у вигляді рядку:


public override string ToString()
{
return NameOfCountry; // + " " + Surname;
}

public static bool operator ==(Country left, Country right)


{
return left.Equals(right);
}

public static bool operator !=(Country left, Country right)


{
return !(left == right);
}
}

// Книжка
public class Album<TCountry>
{
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Title { get; set; }

[System.Xml.Serialization.XmlAttributeAttribute()]
public int Year { get; set; }
// public List<TCountry> Authors { get; set; }

// Конструктори
public Album(string title, int year, Country country)
{
Title = title;
Year =
year;
}
public Album()
{

// Визначення представлення у вигляді рядку


public override string ToString()
{
string s = string.Format("Title: \"{0}\". Year: {1} {2}\n", Title);
return s;
}

// Перевизначення еквівалентності
public override bool Equals(object? obj)
{
if (obj is Album<TCountry> b)
{
if (b.Year.Equals(Year))
{
return false;
}
return b.Title == Title && b.Year == Year;
}
return false;
}
}

// Книжкова полиця
public class CreativeTeam<TCountry>
{
public List<Album<TCountry>> arraysOfSongs { get; set; }

// Конструктор
public CreativeTeam(params Album<TCountry>[] objects)
{
arraysOfSongs = new List<Album<TCountry>>(objects);
}

// Додавання книжки
public void Add(Album<TCountry> album)
{
arraysOfSongs.Add(album);
}

// Індексатор
public Album<TCountry> this[int index]
{
get { return arraysOfSongs[index]; }
set { arraysOfSongs[index] = value; }
}

// Перевантажений оператор додавання книжки


public static CreativeTeam<TCountry> operator
+(CreativeTeam<TCountry> bookshelf, Album<TCountry> book)
{
CreativeTeam<TCountry> newShelf = new() { arraysOfSongs =
bookshelf.arraysOfSongs };
newShelf.Add(book);
return newShelf;
}

// Перевантажений оператор видалення книжки


public static CreativeTeam<TCountry> operator
-(CreativeTeam<TCountry> bookshelf, Album<TCountry> book)
{
CreativeTeam<TCountry> newShelf = new() { arraysOfSongs =
bookshelf.arraysOfSongs };
newShelf.Remove(book);
return newShelf;
}

// Видалення книжки зі вказаними даними


public void Remove(Album<TCountry> book)
{
arraysOfSongs.Remove(book);
}

// Визначення представлення у вигляді рядку


override public string ToString()
{
string result = "";
foreach (Album<TCountry> book in arraysOfSongs)
{
result += book.Title + " " + book.Year + "\n";
}
return result;
}

// Пошук книжки з певною послідовністю літер


public List<Album<TCountry>> ContainsCharacters(string
nameCharacters)
{
List<Album<TCountry>> found = new();
foreach (Album<TCountry> album in arraysOfSongs)
{
if (album.Title.Contains(nameCharacters))
{
// Додаємо новий елемент до списку:
found.Add(album);
}
}
return found;
}

// Читання книжок за допомогою механізму десеріалізації


public bool ReadAlbums(string fileName)
{
XmlSerializer deserializer = new(typeof(List<Album<TCountry>>));
using TextReader textReader = new StreamReader(fileName);
var data = deserializer.Deserialize(textReader);
if (data == null)
{
return false;
}
arraysOfSongs = (List<Album<TCountry>>)data;
return true;
}

// Запис книжок за допомогою механізму серіалізації


public void WriteAlbums(string fileName)
{
XmlSerializer serializer = new(typeof(List<Album<TCountry>>));
using TextWriter textWriter = new StreamWriter(fileName);
serializer.Serialize(textWriter, arraysOfSongs);
}

// Вкладений клас для порівняння книжок за алфавітом назв


class CompareByTitle : IComparer<Album<TCountry>>
{
public int Compare(Album<TCountry>? b1, Album<TCountry>? b2)
{
if (b1 == null || b2 == null)
{
return 0;
}
return string.Compare(b1.Title, b2.Title);
}
}

// Вкладений клас для порівняння книжок за кількістю авторів


class CompareSortByYear : IComparer<Album<TCountry>>
{
public int Compare(Album<TCountry>? b1, Album<TCountry>? b2)
{
if (b1 == null || b2 == null)
{
return 0;
}
return b1.Year < b2.Year ? -1 :
(b1.Year == b2.Year ? 0 :
1);
}
}

// Сортування книжок за алфавітом назв


public void SortByTitle()
{
arraysOfSongs.Sort(new CompareByTitle());
}

// Сортування книжок за кількістю авторів


public void SortByYear()
{
arraysOfSongs.Sort(new CompareSortByYear());
}
}
}

Рисунок 1 - Робота програми

2. Робота з текстовими файлами


Розробити програму, яка здійснює копіювання з одного файлу в інший
рядків, довжина яких не перевищує введеного значення.

Program.cs
using System;
using
System.IO;
using System.Text;

namespace Lab_3_2
{
class Program
{
static void Main(string[] args)
{
int length = 8;

using (StreamReader reader = new StreamReader("From.txt",


Encoding.Default))
{
using (StreamWriter writer = new StreamWriter("To.txt"))
{
string s;
while ((s = reader.ReadLine()) != null)
{
if (s.Length <= length)
{
writer.WriteLine(s);
}
}
}
}
}
}
}
Рисунок 3 - Вхідні дані

Рисунок 4 - Вихідні дані

3. Реалізація серіалізації та десеріалізації


Описати класи Студент та Академічна група (з масивом студентів у якості
поля). Створити об'єкти, здійснити їх серіалізацію в XML-документ та
десеріалізацію.

Program.cs
using System.Xml.Serialization;
using System.IO;
using System;
namespace Lab3_3
{
public class Student
{
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Name { get; set; }

[System.Xml.Serialization.XmlAttributeAttribute()]
public string Surname { get; set; }
public string[] Grades { get; set; }
}

public class AcademicGroup


{
public Student[] student { get; set; }
}

class Test
{
static void Main(string[] args)
{
AcademicGroup academicGroup = new AcademicGroup()
{
student = new Student[]
{
new Student {
Name =
"Frodo",
Surname = "Baggins",
Grades = new string[] { "B", "D", "C" }
},
new Student {
Name = "Oleksandr",
Surname =
"Trufanov",
Grades = new string[] { "A", "A", "B+" }
},
new Student {
Name = "Maksim",
Surname = "Petrovicjev",
Grades = new string[] { "A+", "B", "B+" }
},
new Student {
Name = "Andrew",
Surname =
"Brown",
Grades = new string[] { "C", "A", "C" }
}
}
};

XmlSerializer serializer = new XmlSerializer(typeof(AcademicGroup));


using (TextWriter textWriter = new StreamWriter("XT.xml"))
{
serializer.Serialize(textWriter, academicGroup);
}

XmlSerializer deserializer =
new
XmlSerializer(typeof(AcademicGroup));
using (TextReader textReader = new StreamReader("XT.xml"))
{
academicGroup =
(AcademicGroup)deserializer.Deserialize(textReader);
}
}
}
}

Рисунок 5 - Вихідні дані файлу “XT”

4. Створення бібліотеки узагальнених функцій для роботи з


масивами та списками
Реалізувати статичний клас та реалізувати статичні узагальнені методи, які
реалізують таку функціональність:
● обмін місцями двох груп елементів
● обмін місцями усіх пар сусідніх елементів (з парним і
непарним індексом)
● вставлення у масив (список) іншого масиву (списку) елементів
у вказане місце
● заміна групи елементів іншим масивом (списком)
елементів Реалізувати наведені функції для масивів і для списків.

Program.cs
using System;

namespace Lab3_4
{
public static class ArrayUtils
{
public static void SwapElements<TElem>(TElem[] arr, int iStart, int
iFinish, int jStart, int jFinish)
{
for (int i = 0; i <= iFinish - iStart; i++)
{
// Копіювання одного з елементів у тимчасову комірку:
TElem elem = arr[iStart];
arr[iStart] = arr[jStart];
arr[jStart] = elem;
iStart++;
jStart++;
}
}

public static void SwapElements2<TElem>(TElem[] arr, int index)


{
for (int i = 1; i < 3; i++)
{
// Копіювання одного з елементів у тимчасову комірку:
TElem elem = arr[index + i];
arr[index - i] = arr[index + i];
arr[index + i] = elem;
}
}

public static void Insert<TElem>(ref TElem[] arr, ref TElem[] arr1, int
index)
{
// Зміна розміру масиву:
Array.Resize(ref arr, arr1.Length + arr.Length - 1);

// Зсув елементів уперед шляхом копіювання:


Array.Copy(arr, index + 1, arr, index + arr1.Length, arr1.Length + 1);

Array.Copy(arr1, 0, arr, index, arr1.Length);


}

public static void Insert2<TElem>(ref TElem[] arr, int index1, int index2,
TElem c)
{
for (int i = index1; i < index2; i++)
{
arr[i] = c;
}
}

public static void Print<TElem>(TElem[] arr)


{
foreach (TElem elem in arr)
{
Console.Write("{0, 6}", elem);
}
Console.WriteLine();
}
}

class Program
{
static void Main(string[] args)
{
int[] a = { 112, 23, 32, 45, 34, 57, 70 };
int[] a1 = { 10, 20, 30, };
ArrayUtils.Insert(ref a, ref a1, 2);
ArrayUtils.Print(a);
ArrayUtils.SwapElements2(a, 3);
ArrayUtils.Print(a);
ArrayUtils.Insert2(ref a, 3, 5, 4);
ArrayUtils.Print(a);
ArrayUtils.SwapElements(a, 1, 3, 4, 6);
ArrayUtils.Print(a);
}
}
}
Рисунок 6 - Робота програми

5. Створення власного контейнеру


Створити узагальнений клас для представлення одновимірного масиву,
індекс елементів якого змінюється від визначеного значення From до
значення To включно. Ці значення можуть бути як додатними, так і
від'ємними. Клас повинен мати такі елементи:
● закрите поле – "звичайний" масив (список);
● індексатор;
● властивості (для читання) From та To (доцільно зберігати
тільки From, а To – обчислювати);
● конструктор з параметрами From та To для створення
порожнього масиву;
● конструктор з параметром From та параметром типу масиву
(з атрибутом params);
● перевантажений оператор перетворення у рядок (operator string);
● метод надання ітератору, який забезпечить можливість
обходу елементів за допомогою foreach.
● метод додавання нового елементу;
● метод видалення останнього елементу.
У функції Main() слід здійснити тестування усіх створених елементів
класу.
Необхідно реалізувати два варіанти – на базі масиву та на базі списку.

Program.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace CustomContainer
{
public class CustomArray<T> : IEnumerable<T>
{
private T[] array; // Закрите поле для зберігання масиву елементів

public int From { get; private set; } // Властивість "From" для зберігання
початкового індексу
public int To { get; private set; } // Властивість "To" для зберігання
кінцевого індексу

public int Length => To - From + 1; // Властивість "Length" для


отримання кількості елементів у масиві

public CustomArray(int from, int to)


{
From = from;
To = to;
array = new T[Length]; // Ініціалізація масиву залежно від довжини
}
public CustomArray(int from, params T[] elements)
{
From = from;
To = from + elements.Length - 1;
array = elements; // Ініціалізація масиву з переданими елементами
}

public T this[int index] // Індексатор для доступу до елементів масиву


{
get
{
if (index < From || index > To)
{
throw new IndexOutOfRangeException();
}

return array[index - From];


}
set
{
if (index < From || index > To)
{
throw new IndexOutOfRangeException();
}

array[index - From] = value;


}
}
public static explicit operator string(CustomArray<T> customArray)
{
return string.Join(", ", customArray.array); // Перетворення масиву в
рядок з роздільником ","
}

public IEnumerator<T> GetEnumerator()


{
for (int i = From; i <= To; i++)
{
yield return array[i - From]; // Повернення елементів масиву через
ітератор
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

public void Add(T element)


{
Array.Resize(ref array, Length + 1); // Зміна розміру масиву, додаючи
новий елемент
array[array.Length - 1] = element; // Додавання нового елемента в
кінець масиву
To++; // Збільшення значення "To" на 1
}
public void RemoveLast()
{
if (Length > 0)
{
Array.Resize(ref array, Length - 1); // Зміна розміру масиву,
видаляючи останній елемент
To--; // Зменшення значення "To" на 1
}
}
}

class Program
{
static void Main(string[] args)
{
// Варіант на базі масиву
CustomArray<int> arrayContainer = new CustomArray<int>(0, 4); //
Створення контейнера з індексами від 0 до 4
arrayContainer[0] = 10; // Присвоєння значення елементу за індексом
arrayContainer[3] = 20;
Console.WriteLine($"Elements in arrayContainer:
{(string)arrayContainer}"); // Виведення елементів контейнера

arrayContainer.Add(30); // Додавання нового елемента


Console.WriteLine($"Elements in arrayContainer after adding:
{(string)arrayContainer}");

arrayContainer.RemoveLast(); // Видалення останнього елемента


Console.WriteLine($"Elements in arrayContainer after removing:
{(string)arrayContainer}");

// Варіант на базі списку


CustomArray<string> listContainer = new CustomArray<string>(-2,
"apple", "banana", "cherry"); // Створення контейнера з індексами від -2 до 0
Console.WriteLine($"Elements in listContainer:
{(string)listContainer}");

listContainer[0] = "orange";
Console.WriteLine($"Elements in listContainer after modifying:
{(string)listContainer}");

listContainer.Add("grape");
Console.WriteLine($"Elements in listContainer after adding:
{(string)listContainer}");

listContainer.RemoveLast();
Console.WriteLine($"Elements in listContainer after removing:
{(string)listContainer}");

// Перебір елементів контейнера за допомогою


foreach Console.Write("Elements in arrayContainer
(foreach): "); foreach (int element in arrayContainer)
{
Console.Write(element + " ");
}
Console.WriteLine();
Console.Write("Elements in listContainer (foreach): ");
foreach (string element in listContainer)
{
Console.Write(element + " ");
}
Console.WriteLine();
}
}
}

Рисунок 7 - Робота програми

6. Робота з множиною
Увести кількість елементів майбутньої множини цілих чисел та діапазон
чисел. Сформувати цю множину з випадкових значень. Вивести елементи
множини, відсортовані за збільшенням.

Program.cs
using System;
using System.Collections.Generic;
namespace Lab3_6
{
class Program
{
static void Main(string[] args)
{
SortedSet<int> set = new SortedSet<int>();

Console.Write("Введіть початок діапазону чисел: ");


int start = Convert.ToInt32(Console.ReadLine());

Console.Write("Введіть кінець діапазону чисел:


"); int finish =
Convert.ToInt32(Console.ReadLine());

Random random = new Random();

for (int i = 0; i < 10; i++)


{
int k = random.Next(start, finish);
set.Add(k);
}

Console.WriteLine("Відсортовані елементи множини:");

foreach (int k in set)


{
Console.Write("{0} ", k);
;
}
}
}
}

Рисунок 8 - Робота програми

7. Робота з асоціативним масивом


Увести речення та вивести усі різні літери, які входять у речення та їх
кількість входження.

Program.cs
using System;
using System.Collections.Generic;

class Program
{
static void Main()
{
Console.Write("Введіть речення: ");
string sentence = Console.ReadLine();

Dictionary<char, int> charCounts = new Dictionary<char, int>();

foreach (char c in sentence)


{
if (char.IsLetter(c))
{
if (charCounts.ContainsKey(c))
{
charCounts[c]++;
}
else
{
charCounts[c] = 1;
}
}
}

Console.WriteLine("Різні літери та їх кількість входжень:");

foreach (KeyValuePair<char, int> entry in charCounts)


{
Console.WriteLine("Літера {0}: {1} входжень", entry.Key,
entry.Value);
}
}
}
Рисунок 9 - Робота програми

Висновок: У результаті виконання даної роботи ми успішно


ознайомилися з концепцією узагальненого програмування (generics) в мові
C# та його практичним застосуванням.

Узагальнене програмування дозволяє нам створювати універсальні класи,


структури, інтерфейси та методи, які можуть працювати з різними
типами даних. Це дозволяє нам писати загальні, повторно
використовувані компоненти програмного забезпечення, зберігаючи при
цьому безпеку типів.

Під час вивчення узагальненого програмування ми ознайомилися з


синтаксисом визначення узагальнених типів та методів, використанням
параметрів типу і обмежень типів. Ми також розглянули переваги, які
узагальнене програмування надає, такі як безпека типів, ефективніша
робота з колекціями та можливість створення загальних алгоритмів.

Практичне застосування узагальненого програмування включає створення


універсальних структур даних, таких як списки, черги, стеки і т.д., які
можуть працювати з будь-яким типом даних. Ми також можемо
використовувати узагальнені методи для створення загальних алгоритмів,
які можуть бути застосовані до різних типів даних без необхідності
повторного написання коду.

Отримані знання та навички з узагальненого програмування дозволять нам


писати більш гнучкий, повторно використовуваний і ефективний код, що
спрощує розробку та підтримку програмного забезпечення. Узагальнене
програмування є потужним інструментом, який допомагає нам створювати
більш масштабовані та гнучкі програми з меншими зусиллями.

You might also like