- •1 Завдання на лабораторну роботу
 - •1.1 Індивідуальне завдання
 - •2 Методичні вказівки
 - •2.1 Ініціалізатори об'єктів
 - •2.1 Статичні класи
 - •2.1.3 Методи, які розширюють існуючі класи
 - •6 Перевантаження операцій
 - •2.8 Успадкування
 - •2.1 Поліморфізм. Інтерфейси
 - •2.2 Структури і перелічення
 - •2.3 Вкладені типи
 - •3 Приклади програм
 - •3.1 Ієрархія об'єктів реального світу
 - •3.2 Знаходження мінімуму методом дихотомії
 - •3.3 Ієрархія книжкових полиць
 - •4 Вправи
 - •5 Контрольні запитання
 
3.2 Знаходження мінімуму методом дихотомії
Припустимо, необхідно створити універсальний клас для знаходження методом дихотомії мінімуму будь-якої функції f(x). Алгоритм знаходження мінімуму на певному інтервалі [a, b] з точністю h полягає в наступному:
визначається середина інтервалу (x)
обчислюються значення f(x - h) та f(x + h)
якщо f(x - h) > f(x + h), початок інтервалу переноситься в x, в іншому випадку туди переноситься кінець інтервалу
якщо довжина нового інтервалу менша, ніж h, процес завершується, в іншому випадку - повторюється для нового інтервалу
Слід зазначити, що цей алгоритм працює тільки для випадку, коли на інтервалі один мінімум.
Можна запропонувати два підходи: через використання абстрактних класів і через використання інтерфейсів.
Перший варіант
Створюємо новий клас - AbstractMinimum, який містить абстрактну функцію F() і функцію знаходження мінімуму - Solve(). У похідному класі ця функція перекривається.
using System;
using System.Collections.Generic;
namespace LabSecond
{
public abstract class AbstractMinimum {
abstract public double F(double x);
public double Solve(double a, double b, double h)
{
double x = (a + b) / 2;
while (Math.Abs(b - a) > h) {
if (F(x - h) > F(x + h))
a = x;
else
b = x;
x = (a + b) / 2;
}
return x;
}
}
class SpecificMinimum : AbstractMinimum
{
public override double F(double x)
{
return x * x - x;
}
}
class Program
{
static void Main(string[] args)
{
SpecificMinimum sm = new SpecificMinimum();
Console.WriteLine(sm.Solve(0, 3, 0.000001));
}
}
}
Другий варіант
Описуємо інтерфейс для представлення функції. Клас Solver реалізує статичний метод для знаходження функції. Клас, який реалізує інтерфейс, містить конкретну реалізацію функції F().
using System;
using System.Collections.Generic;
namespace LabSecond
{
public interface IFunction
{
double F(double x);
}
public class Solver
{
public static double Solve(double a, double b, double h, IFunction func)
{
double x = (a + b) / 2;
while (Math.Abs(b - a) > h)
{
if (func.F(x - h) > func.F(x + h))
a = x;
else
b = x;
x = (a + b) / 2;
}
return x;
}
}
class MyFunc : IFunction {
public double F(double x) {
return x * x - x;
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Solver.Solve(0, 3, 0.000001, new MyFunc()));
}
}
}
3.3 Ієрархія книжкових полиць
Припустимо, необхідно доробити попередньо створену програму, яка описує книжкову полицю, додавши ієрархію книжкових полиць. Наприклад, окремий тип полиці - полиця з назвою. Для обох варіантів книжкових полиць слід визначити операції додавання книжок (+) та видалення книжок (-). Для всіх класів також необхідно перекрити метод ToString(), для книжок та авторів - також Equals(). Для представлення автора необхідно створити окрему структуру.
Наведемо повний текст програми:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LabSecond
{
// Структура для опису автора
public struct Author
{
public string Surname, Name;
// Перевизначення еквівалентності
public override bool Equals(object obj)
{
Author author = (Author) obj;
return author.Surname == Surname && author.Name == Name;
}
// Визначення представлення у вигляді рядку:
public override string ToString()
{
return Name + " " + Surname;
}
// Визначається у парі з Equals()
public override int GetHashCode()
{
return base.GetHashCode();
}
}
// Книжка
public class Book
{
public string Title { get; set; }
public int Year { get; set; }
public Author[] Authors { get; set; }
// Конструктор
public Book(string title, int year, params Author[] authors)
{
Title = title;
Year = year;
Authors = authors;
}
// Визначення представлення у вигляді рядку
// string.Format() забезпечує форматування, аналогічне Console.WriteLine()
public override string ToString()
{
string s = string.Format("Назва: \"{0}\". Рiк видання: {1}", Title, Year);
s += "\n" + " Автор(и):";
for (int i = 0; i < Authors.Length; i++)
{
s += string.Format(" {0}", Authors[i]);
if (i < Authors.Length - 1)
s += ",";
else
s += "\n";
}
return s;
}
// Перевизначення еквівалентності
public override bool Equals(object obj)
{
Book b = obj as Book;
if (b != null)
{
if (b.Authors.Length != Authors.Length)
return false;
for (int i = 0; i < Authors.Length; i++)
{
if (!b.Authors[i].Equals(Authors[i]))
return false;
}
return b.Title == Title && b.Year == Year;
}
return false;
}
// Визначається у парі з Equals()
public override int GetHashCode()
{
return base.GetHashCode();
}
}
// Книжкова полиця
public class Bookshelf
{
public Book[] Books { get; set; }
// Конструктор
public Bookshelf(params Book[] books)
{
Books = books;
}
// Індексатор
public Book this[int index]
{
get { return Books[index]; }
set { Books[index] = value; }
}
// Визначення представлення у вигляді рядку
public override string ToString()
{
string result = "";
foreach (Book book in Books)
result += book;
return result;
}
// Пошук книжки з певною послідовністю літер
public Book[] ContainsCharacters(string characters)
{
Book[] found = new Book[0];
foreach (Book book in Books)
{
if (book.Title.Contains(characters))
{
// Додаємо новий елемент до масиву:
Array.Resize(ref found, found.Length + 1);
found[found.Length - 1] = book;
}
}
return found;
}
// Додавання книжки
public void Add(Book book)
{
Book[] books = Books;
Array.Resize(ref books, Books.Length + 1);
Books = books;
Books[Books.Length - 1] = book;
}
// Видалення книжки зі вказаними даними
public void Remove(Book book)
{
int i, k;
Book[] newBooks = new Book[Books.Length];
for (i = 0, k = 0; i < Books.Length; i++, k++)
{
if (Books[i].Equals(book))
k--;
else
newBooks[k] = Books[i];
}
if (i > k)
Array.Resize(ref newBooks, Books.Length - 1);
Books = newBooks;
}
// Перевантажений оператор додавання книжки
public static Bookshelf operator+(Bookshelf bookshelf, Book book)
{
Bookshelf newBookshelf = new Bookshelf(bookshelf.Books);
newBookshelf.Add(book);
return newBookshelf;
}
// Перевантажений оператор видалення книжки
public static Bookshelf operator-(Bookshelf bookshelf, Book book)
{
Bookshelf newBookshelf = new Bookshelf(bookshelf.Books);
newBookshelf.Remove(book);
return newBookshelf;
}
}
// Книжкова полиця з назвою
public class TitledBookshelf : Bookshelf
{
public string Title { get; set; }
public TitledBookshelf(string title, params Book[] books) : base(books)
{
Title = title;
}
// Визначення представлення у вигляді рядку
public override string ToString()
{
return Title + "\n" + base.ToString();
}
// Перевантажений оператор додавання книжки
public static TitledBookshelf operator +(TitledBookshelf titled, Book book)
{
TitledBookshelf newBookshelf = new TitledBookshelf(titled.Title, titled.Books);
newBookshelf.Add(book);
return newBookshelf;
}
// Перевантажений оператор видалення книжки
public static TitledBookshelf operator -(TitledBookshelf titled, Book book)
{
TitledBookshelf newBookshelf = new TitledBookshelf(titled.Title, titled.Books);
newBookshelf.Remove(book);
return newBookshelf;
}
}
class Program
{
static void Main(string[] args)
{
// Створюємо порожню полицю:
Bookshelf bookshelf = new Bookshelf();
// Додаємо книжки
bookshelf += new Book("The UML User Guide", 1999, new Author() { Name = "Grady", Surname = "Booch" },
new Author() { Name = "James", Surname = "Rumbaugh" },
new Author() { Name = "Ivar", Surname = "Jacobson" });
bookshelf += new Book(@"Об'єктно-орiєнтоване моделювання програмних систем", 2007,
new Author() { Name = "Iгор", Surname = "Дудзяний" });
bookshelf += new Book("Thinking in Java", 2005, new Author() { Name = "Bruce", Surname = "Eckel" });
// Виводимо дані на екран:
Console.WriteLine(bookshelf);
Console.WriteLine();
// Шукаємо книжки з певною послідовністю літер:
Console.WriteLine("Уведiть послiдовнiсть лiтер:");
string sequence = Console.ReadLine();
Bookshelf newBookshelf = new Bookshelf(bookshelf.ContainsCharacters(sequence));
// Виводимо результат на екран:
Console.WriteLine("Знайденi книжки:");
Console.WriteLine(newBookshelf);
Console.WriteLine();
// Видаляємо книжку про Java
Book javaBook = bookshelf[2]; // індексатор
bookshelf -= javaBook;
Console.WriteLine("Пiсля видалення книжки:");
Console.WriteLine(bookshelf);
Console.WriteLine();
// Створюємо нову полицю
TitledBookshelf titledBookshelf = new TitledBookshelf("Java");
titledBookshelf += javaBook;
Console.WriteLine("Нова полиця:");
Console.WriteLine(titledBookshelf);
}
}
}
