Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

osn_progr_final

.pdf
Скачиваний:
37
Добавлен:
12.02.2016
Размер:
3.27 Mб
Скачать

шляхом створення загального для них стандартного інтерфейсу для реалізації схожих дій.

Об'єктно-орієнтоване проектування - це методологія проектування, що сполучає в собі процес об'єктної декомпозиції і прийоми представлення логічної і фізичної, а також статичної і динамічної моделей проектованої системи.

Розглянемо основні ідеї об'єктно-орієнтованого підходу:

-програма є моделлю деякого реального процесу;

-об'єкт описується набором параметрів, значення яких визначають стан об'єкту, і набором операцій (методів), які може виконувати об'єкт;

-об'єкти, описані одним і тим же набором параметрів і здатні виконувати один і той же набір дій, є класом однотипних об'єктів.

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

Таким чином, об'єктно-орієнтований підхід припускає, що при розробці програми повинні бути визначені класи використовуваних в програмі об'єктів і побудовані їх описи, потім створені екземпляри необхідних об'єктів і визначено взаємодію між ними.

Але на об'єктно-орієнтованому програмуванні розробка нових технологій не завершилася. Зараз на базі ООП розвивається нова технологія – COM.

COM розшифровується як Component Object Model - компонентна об'єктна модель. Суттю даної технології є те, що програми будуються з компонент, які складаються з об'єктів. Таким чином, можна сказати, що ця технологія виросла з модульного і об'єктноорієнтованого підходу до побудови програм. Новизною можна рахувати те, що цими компонентами і об'єктами - є безпосередньо виконуваний двійковий код. Не початкові тексти, що не включаються та компілюються сумісно з проектом, не «бібліотеки стандартних програм», що приєднуються лінкером, а безпосередньо виконувані файли, які ніяк не треба «пов'язувати» із своїм проектом - їх достатньо зареєструвати в операційній системі і вони будуть доступні будь-якій програмі, що виконується на даній машині. Тобто їх використання в своїй програмі проводиться «без використання операцій збірки модуля».

21

Таким чином, COM є технологія, яка переносить всі переваги ООП, доступні програмісту на рівні початкового тексту, на двійковий рівень.

Слід також надати увагу технології, що набирає оберти - .NET. Хоча даний підхід і не можна розглядати, як чисто програмістський. Це швидше використовування якоїсь платформи для розв’язання сучасних задач. Використання суфікса .NET може не лише вказувати на наявність в продукті конкретних нових технологій, але і відображати напрямок його розвитку.

Свого часу Б.Гейтс заявив, що він хоче, щоб запам'ятали хоча б одну фразу відносно технології .Net: "Програмне забезпечення для об'єднання інформації, користувачів, систем і пристроїв".

Але розгляд останніх двох технологій не є метою цієї книги.

22

2. ОСНОВИ АЛГОРИТМІЗАЦІЇ

2.1 ПОНЯТТЯ АЛГОРИТМУ.

Алгоритм повинен бути визначений настільки чітко, щоб його вказівки міг виконувати навіть комп'ютер.

Дональд Е. Кнут

Метою програмування є опис процесів обробки даних. Введемо деякі визначення.

Визначення 1. Дані - це представлення фактів і ідей у формалізованому вигляді, придатному для передачі і переробки в деякому процесі.

Визначення 2. Інформація - це зміст, який надається даним при їх представленні.

Визначення 3. Обробка даних - це виконання систематичної послідовності дій з даними.

Визначення 4. Сукупність носіїв даних, які використовуються при якій-небудь обробці даних, називатимемо інформаційним середовищем.

Визначення 5. Набір даних, що містяться в який-небудь момент в інформаційному середовищі, називатимемо станом цього інформаційного середовища.

Визначення 6. Процес обробки даних можна визначити як послідовність змін станів деякого інформаційного середовища.

Описати процес – це означає визначити послідовність станів заданого інформаційного середовища. Якщо ми хочемо, щоб згідно з заданим описом необхідний процес породжувався автоматично на якому-небудь комп'ютері, необхідно, щоб цей опис був формалізованим. Такий опис називається програмою.

Основним в процесі програмування є розробка алгоритму. Це один з найскладніших етапів розв’язання задачі з використанням комп'ютерів.

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

23

Алгоритм - це деяке правило перетворення інформації, застосування якого до заданої (початкової) інформації приводить до результату - нової інформації.

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

Основна увага в теорії алгоритмів надається методам задання (описи, конструювання) алгоритмів - форматам запису.

Загально прийнято оперувати з мовою блок-схем. Інший різновид мови задання алгоритмів є діаграми Насси-Шнейдермана. Ми, для простоти, використовуватимемо словесний опис. Але навіть таке спрощення надалі дозволить нам швидко перейти до написання програм.

Алгоритми мають такі властивості:

1.Элементарність. Кожна команда з набору команд містить вказівку виконати деяку елементарну дію, що однозначно розуміється і точно виконується.

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

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

4.Результативність. Виконання будь-якого алгоритму повинне бути закінчене через скінчену кількість кроків з деяким результатом.

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

Алгоритми в процесі своєї роботи для отримання результату обробляють деякі дані, тобто алгоритми мають вхід (вхідні дані) і вихід (результат). Слід підкреслити, що вхідні дані потрібні не усякому алгоритму.

Окрім вхідних і вихідних даних, як правило, алгоритм передбачає тимчасове формування проміжних даних або ще їх називають допоміжними. Тобто ще однією характеристикою алгоритму є кількість пам’яті, яку він використовує.

24

При конструюванні алгоритму слід суворо визначити кожен його крок, передбачивши будь-які можливі стани процесу і відповідні інструкції для їх обробки. Лише такий алгоритм гарантує однозначне здобуття необхідного результату, і класифікується як детермінований. Щодо такого алгоритму можна стверджувати, що його неодноразове застосування до однакових вхідних даних завжди приводить до одного і того ж результату. Стохастичні алгоритми ми розглядати не будемо.

2.2 КЛАСИФІКАЦІЯ ВНУТРІШНІХ СТРУКТУР АЛГОРИТМІВ.

Основними алгоритмічними структурами є лінійність, розгалуження та цикл.

Лінійні структури

Прості задачі мають лінійний алгоритм розв’язання. Це означає, що він не містить перевірок умов і повторень.

Приклад 1. За даними довжинами катетів а, b обчислити площу прямокутного трикутника

Вхід: числа а,b

1.Ввести а, b.

2.S= a*b/2.

3.Вивести значення S.

4.Кінець.

Вихід: значення площі S.

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

Структура - розгалуження

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

Приклад 2. Алгоритм розв’язання квадратного рівняння ax2 + bx + с = 0;

Вхід: Коефіцієнти а, b і с з рівняння ax2 + bx + с = 0;

25

1.Обчислити D = b2 – 4ac;

2.Якщо D < 0 то (відповісти “Розв’язків немає”; Перейти до

6);

3.Якщо D = 0 то (обчислити x = -b/(2a); Перейти до 6);

4.Обчислити x1 = (-b+sqrt (D))/(2a);

5.Обчислити x2 = (-b-sqrt(D))/(2a);

6.Закінчити роботу.

Вихід: “Розв’язків немає” або корінь x або корінь x1, x2.

В даному прикладі використовується команда виду: Якщо <умова> то (<послідовність команд>)

Виконуючи цю команду, необхідно перевірити істинність умови. Якщо умова виконана, то здійснюємо перехід до виконання першої команди з послідовності команд, що стоїть після слова «то» і після цього переходимо до виконання наступних лінійних команд. Інакше, тобто коли умова помилкова, то пропускаємо (<послідовність команд>) і переходимо до виконання наступної команди. Такі команди називають умовними або розгалуженнями.

При тестуванні алгоритмів з розгалуженнями необхідно підбирати такі початкові дані, щоб можна було перевірити всі гілки.

Циклічні структури.

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

Приклад 3. Підрахувати кількість цифр в записі натурального числа n.

Ідея розв’язання. Із заданого числа вибираємо з молодшого розряду цифру за цифрою до того часу, поки воно (число) не вичерпається, тобто стане рівним нулю. При цьому кожна цифра враховується, тобто підраховується їх кількість.

Вхід: Число n.

1.Ввести число n

2.К= 0 {готуємо лічильник кількості цифр}

3.Якщо n = 0, перехід до п. 7

4.K= К +1

5.n = n div 10

6.Перехід до п. 3

26

7.Друк К

8.Кінець

Вихід: кількість цифр К.

Слід мати на увазі, що при конкретній реалізації даного алгоритму в середовищі конкретної мови програмування можна використовувати як цикли з передумовою, так і цикли з післяумовою.

Приклад 4. Алгоритм Евкліда обчислення найбільшого спільного дільника цілих додатних чисел А і B: НСД(А, B).

Вхід А, B;

1.Обчислити U = А;

2.Обчислити V = B;

3.Поки U <> V виконувати

4.Якщо U < V

5.то Обчислити V = V - U

6.інакше Обчислити U = U - V;

7.Обчислити D = U.

Вихід: D - найбільший спільний дільник А і B.

В даному прикладі використана команда повторення. Вона має вигляд:

Поки <Умова> виконувати <Команда> При виконання цієї команди спочатку перевіряється істинність

Умови. Якщо Умова істинна, виконуємо Команду, вказану після слова «виконувати» і повторюємо перевірку Умови. Виконання Команди і перевірка Умови повторюються до тих пір, поки Умова істинна. Якщо Умова помилкова, переходимо до виконання команди, наступної за командою повторення. У цьому ж прикладі використаний ще один різновид команди розгалуження - команда виду

Якщо <Умова> то <Команда 1> інакше < Команда 2> Виконуючи цю команду, спочатку перевіряється Умова. Якщо

Умова виконана, виконується Команда 1, інакше виконується команда 2. Далі переходимо до наступної команди. Помітимо, що команда повторення, як і команди розгалуження, містять в собі інші команди.

27

2.3 СКЛАДНІСТЬ АЛГОРИТМІВ .

Дивно, скільком програмістам доводиться дуже дорогим способом з'ясовувати, що їх програма не може обробити вхідні дані раніше, ніж через декілька днів машинного часу. Краще було б передбачити такі випадки за допомогою олівця і паперу.

К.Гудман, С.Хедетніємі

Природньо, що перед розробкою програми слід продумати, як розв’язувати поставлену задачу. При розробці алгоритму слід, перш за все, надавати увагу часу його роботи і об'єму пам'яті, яку необхідно витратити для зберігання і обробки даних. Останні можна розділити на вхідну інформацію (вхідне слово), дані, що вимагають проміжного зберігання і вихідну інформацію (вихідне слово). При цьому, слід брати до уваги той факт, що не всі дані вимагають одночасного зберігання і використання, а тому можна планувати роботу по ефективному їх використанню.

Для розв’язання даної задачі можна написати багато різних алгоритмів. Чим ці алгоритми відрізняються між собою, який краще використовувати? Як визначити поняття краще? Такі питання виникають ( або повинні виникати) у професійного програміста.

Для початку, замінимо поняття «краще» на «ефективніше» і далі по тексту будемо його використовувати.

Ефективність програми є дуже важливою її характеристикою. Вона має дві складові: розмір і час.

Розмір вимірюється кількістю пам'яті, що вимагається для виконання програми. Іноді кількість необхідної пам'яті є домінуючим фактором в оцінці ефективності програм. Проте останніми роками ця складова ефективності поступово втрачає своє значення.

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

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

28

Основною властивістю алгоритму є виконання поставленої задачі за скінченну кількість кроків. Швидкість, з якою алгоритм виконується на конкретному пристрої, може істотно залежати від набору вхідних даних. При цьому швидкий "в середньому" алгоритм здатний давати збої в окремих "поганих" випадках. Якщо задача повинна напевно розв'язуватися за певний час роботи процесора, то в цьому випадку, ймовірно, ми віддамо перевагу алгоритму повільнішому в середньому, зате надійному в гірших ситуаціях. Уміння передбачати "нехороші" ситуації якраз і відрізняє кваліфікованого алгоритміста від звичайного кодувальника.

Будь-який крок алгоритму реалізується за допомогою деякої кількості машинних операцій. По суті, потрібна деталізація алгоритму до такого ступеня, щоб відносно окремого кроку не потрібним було його подальше алгоритмічне опрацьовування. Тут можливі лише дві ситуації: або фіксований час виконання такого кроку визначено деяким набором простих, без циклів, команд мови програмування, або йдеться про "укрупнений" крок, відносно якого відповідний аналіз вже проводився і результати відомі.

Тепер перейдемо до головного питання, яке можна задати будьякому програмісту: чи припинить його програма своє виконання або ж працюватиме до нескінченості. За теоремою, доведеною Тюрінгом в 30-і роки, не існує алгоритму, що дає відповідь на це питання, тобто проблема зупинки нерозв'язна. Таким чином, навіть якщо ми маємо алгоритм, який розв’язує поставлену задачу, то ще не відомо чи приведе він нас до розв’язку.

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

(загальний час роботи) = (кількість операцій алгоритму) * (час на одну операцію).

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

Розглянемо деякі приклади.

Приклад 1. Алгоритм обміну значень двох змінних цілого типу - а і b - реалізується, в загальному випадку, за три кроки, незалежно від того, до якого типу простих даних він застосовується:

29

temp = а а = b

b = temp

Якщо застосуємо для обміну значеннями алгоритм, який використовує арифметичні операції, то одержимо таку послідовність дій:

x = x+y

у = x-у

x = x-у

При цьому одержимо також три кроки.

Приклад 2. Знайти суму натуральних чисел від 1 до заданого n. Якщо скористатися відомою формулою для суми арифметичної

прогресії, то обчислення також зажадають лише 3 кроки: додавання, множення і ділення. Якщо ж реалізувати обчислювальний процес як циклічний (цикл з параметром), управляюча змінна "пробіжить" значення від 1 до n, - то доведеться виконати n кроків алгоритму.

Сумнівів, який з алгоритмів більш ефективний, здається, не виникає.

Для алгоритмів, подібних до тільки що розглянутого, - n кроків для обробки n вхідних значень, - ми маємо, що кількість кроків є функцією від числа елементів, що обробляються. Можна вважати, що кількість кроків є функцією від кількості елементів - g(n). Не для всякого алгоритму таку функцію можна знайти і обчислити.

Скористаємося для оцінки швидкості зростання функції, що нас цікавить, порівнянням її з функцією, чия поведінка добре досліджена. При дослідженні поведінки функцій g(n) натурального n розглядатимемо такі функції g(n), що ростуть не швидше ніж f(n). Тобто, існує така пара додатних значень M і n0, що |g(n)|≤M|f(n0)| для n≥n0. Або можна сказати що функція g(n) - порядку f(n) для великих n. Таку залежність позначають в математиці символом О.

Вкажемо декілька важливих властивостей O-оцінювання:

1.f(n)=O(f(n))

2.c·O(f(n))=O(f(n)), де с - деяка константа

3.О(f(n))+O(f(n))=O(f(n))

4.О(О(f(n)))=O(f(n))

5.О(f(n))·О(g(n))=O(f(n)·g(n))

6.О(k*f)=O(f), де к-деяка константа

7.О(f+g) дорівнює домінанті О(f) і О(g).

Тут с, n позначають константи, а f і g - функції.

30

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]