АЛГОРИТМИ И БС (Задачи)

Както обещах, този път ще си говорим за малко по-сложни неща от последния пост. Започваме с размяна стойностите на две променливи, а след това ще си говорим за цикли и тяхната употреба.

Най-разпространени са два алгоритъма. В единия разменяме променливите, използвайки свойствата за събиране и изваждане в математиката. Ето как изглежда псевдокодът на този алгоритъм:

начало
нека а и b са целочислени числа
въведи а и b
a:=a+b {а получава стойност а+b}
b:=a-b {b получава стойност а-b}
край.

Можеш ли вече да направиш сам блок-схемата?


Всъщност третият блок (блокът за елементарни операции) е "обединение" на два такива блока с по една операция във всеки. На практика обаче е важна последователността на операциите и самите операции.

Време е да тестваме алгоритъма си :)

Въвеждаме a:=5 и b:=3
a:=a+b   a:=5+3 => а=8 (а има стойност 8)
b:=a-b   b:=8-3 => b=5
a:=a-b  a:=8-5 => a=3


В крайна сметка въведохме a:=5 и b:=3, а алгоритъмът извърши размяната, така че на края имаме a=3 и b=5. 

Другият, може би по-масово използван алгоритъм поради по-лесната си логика, е алгоритъмът за размяна на две променливи чрез допълнителна променлива (помощна).

Псевдокод:

начало
нека a, b и с са целочислени числа
въведи a и b
c:=a
a:=b
b:=a
край.

Ето я и съответната блок-схема:


Ще използваме същия пример и за този алгоритъм:

Въвеждаме a:=5 и b:=3
Въвеждаме a:=5 и b:=3
a:=a   c:=5 => c=5
a:=b   a:=3 => a=3
b:=c  a:=5 => b=5

Резултат: a=3 и b=5
Кой от двата метода ще използваш - зависи от теб!

ЦИКЛИ

Нека се върнем на една от задачите от последния урок - ако си направил блок-схемата за намиране на най-голямото от четири числа, си се убедил колко сложно изглежда. А какво ще стане с 5,6 или 7 числа? Как изобщо ще реализираме задача с n числа?

Отговорът се крие в използването на цикли. Цикълът е част от програма (алгоритъм), която трябва да се повтори определен брой пъти, за да се реши задачата. Цикълът се състои от тяло и условие. Тялото е съвкупността от операции, която трябва да се изпълни за една итерация. Условието се състои от условен блок, чийто резултат определя дали тялото трябва да се изпълни още един път или не. В зависимост от условието, циклите се делят на два вида:

-с предусловие - условието се намира преди тялото. Това означава, че първо се проверява условието и после тялото МОЖЕ да се изпълни. Характерна черта на този вид цикли е, че тялото може и да НЕ се изпълни нито веднъж! 
-с постусловие - условието се намира след тялото. Това означава, че тялото на цикъла винаги ще се изпълни поне веднъж, преди да се провери условието му.

Всеки алгоритъм може да се модулира и с двата вида цикли, но понякога практиката показва, че използването на единия вид е по-подходящо от използването на другия. Как изглежда най-простата схема на един цикъл:

-Предусловие:

ВАЖНО: Блоковете за инструкция и въвеждане/извеждане НЕ са задължителни! Това означава, че може да се използват двата заедно, само един от тях или никой (последното е малко безсмислено), както и комбинации - например въвеждане, две инструкции, извеждане . Също така е важно да се забележи, че за езикът С, който ще учим, цикълът с предусловие се изпълнява при резултат от условието ДА! В моментът, в който условието е с резултат НЕ програмата "излиза" от цикъла и той спира да се изпълнява.

-Постусловие

Както при другия вид условие, така и тук, тялото се изпълнява ДОКАТО условието е вярно. Единствената особеност е, както вече казах и вероятно тук е по-нагледно, че при постусловие, тялото се изпълнява поне веднъж!

А сега малко примери и задачи:

Нека развием алгоритъма за намиране на най-голямото от n числа чрез псевдокод:

начало
нека n,a и max и i са целочислени числа
въведи n
max:=0
i:=0 
докато i<n
      въведи а
      ако a>max
            max:=a
      i:=i+1
край.

Блок-схема:



Max пази най-голямата стойност, въведена до момента. За да изведем резултатът, всъщност трябва просто да изведем max. i се нарича брояч - променлива, която следи колко итерации има до момента, както и участва в условието на цикъла. Възможно е тези две функции да са неизпълними със само една променлива, но такива случай ще разгледаме по-късно.

Стана малко по-сложно, нали? Ами.. вземи един лист и си "разиграй" няколко примера :) 

Намери ли случай, в който нашият алгоритъм няма да работи? Замисли се какво ще стане ако въвеждаме само отрицателни стойности. От началото, нашата променлива max е със стойност нула, така че връщайки нейния резултат накрая ще получим нула, докато най-голямото въведено число може и да е отрицателно. Как ще се реши този проблем? Един от начините е да прочетем първото число преди тялото на цикъла и да присвоим стойността му на max. Внимавай с брояча, тъй като числата трябва да са n на брой, а не n+1!

ЗАДАЧИ:

1) Напиши псевдокодът и блок-схемата на задача, която намира най-голямото от n числа, дори и ако всички въведени числа са отрицателни.
2) Напиши псевдокодът и блок-схемата на задача, която намира най-малкото от n числа
3) Напиши псевдокодът и блок-схемата на задача, която намира сумата на n числа
4) Напиши псевдокодът на задача, която въвежда 1 число n. Ако то е положително - намира сумата на n числа, ако е отрицателно - намира най-малкото от следващите n числа.

Успех!

ПП: Ако имаш затруднение - не се стеснявай да оставиш коментар или да ми изпратиш email!

Алгоритми и блок-схеми

АЛГОРИТМИ

Алгоритъмът е съвкупност от разбираеми инструкции, които водят до решението на даден проблем/задача. Алгоритъмът не е задължително термин в програмирането. Пример за алгоритъм извън програмирането е ходенето на работа или училище. За мен този алгоритъм изглежда по следния начин:

1. Излизам от вкъщи в 7:00ч
2. Пътувам с автобус, метро, автобус
3. Пристигам в училище

Всъщност това е доста суров пример - в програмирането тези три стъпки ще трябва да се разбият на повече по-прости команди. Вероятно най-прост алгоритъм в програмирането е алгоритъмът за намиране на по-голямото от две числа. В псевдокод (код на "несъществуващ език за програмиране", който обяснява инструкциите, нужни за решаването на задача - за повече информация) алгоритъмът би изглеждал така:

начало
Нека а и b са целочислени числа
Въведи а и b
Ако a е по-голямо от b:
        изведи а
иначе:
        изведи b
край.


Всъщност този алгоритъм, макар и много прост, в някой ситуации може и да не върне очакваният от нас резултат, но за това по-късно.


БЛОК-СХЕМИ

Съществуват и други начини за представяне на даден алгоритъм. Може би най-нагледният от тях, макар и по-трудоемък за изготвяне, са блок-схемите. Това са схеми от различни блокове, изобразяващи графично инструкциите на нашия алгоритъм, които компютърът може да изпълни. Всички инструкции, които компютърът може да изпълни, се свеждат до следните блокове:



1. БЛОК ЗА НАЧАЛО/КРАЙ
Всеки алгоритъм и всяка програма имат начало и край. Първият блок се използва за обозначаване на начало и край на алгоритъма. Блокът за НАЧАЛО няма вход и има само 1 изход, а блокът за край - има само един вход  и няма изходи.

2. БЛОК ЗА ВХОД/ИЗХОД
Както вече знаем, алгоритъмът е сбор от инструкции. За да получим решението на нашата задача, трябва да имаме входни данни и резултат (изходни данни). Този блок има 1 вход и един изход.

3. БЛОК ЗА ЕЛЕМЕНТАРНИ ОПЕРАЦИИ
Споменахме, също че компютърът изпълнява инструкции (операции), които може да разбере. С този блок изобразяваме самата инструкция, в която извършваме например изчисленията в нашия алгоритъм. 1 вход, 1 изход

4. УСЛОВЕН БЛОК
Условният блок е единственият блок, който ни дава възможност да "разклоним" алгоритъма - с други думи, в зависимост от информацията, която подаваме на входа му, да очакваме различен резултат в края му. Блокът е чисто и просто сравнителна функция или сбор от такива. 1 вход, 2 изхода!!! Единият изход "връща" резултат ДА на сравнителната функция, а другия - НЕ

5. БЛОК ЗА ПОДАЛГОРИТЪМ
При създаване на блок-схеми на по-обемни и сложни алгоритми имаме нужда от "съкращение" на записа. Веднъж създали блок-схема, която решава дадена задача, можем да използваме нейния алгоритъм като един единствен самостоятелен блок. 1 вход, 1 изход

ПРИМЕР:
Нека визуализираме алгоритъма за намиране по-голямото от две числа (препоръчвам ви да опитате сами преди да видите резултата.)



Успя ли сам? БРАВО!
Ако пък сгреши - не се притеснявай, това е само първият опит, има още много време! Сега е време да си обясниш сам с примери алгоритъма и неговата блок-схема. Да, тази може и да е лесна, но има доста по-сложни и разклонени главоблъсканици!

ОБЯСНЕНИЕ:
1) Начало на програмата
2) Въвеждаме а и b
3) Сравняваме а и b
4) Извеждаме a ИЛИ b, в зависимост от стойностите, които сме въвели
4) Край на програмата

ПРИМЕР:
1) Начало
2) въвеждаме а по следния начин: a:=5   Знакът := (двоеточие равно) се чете получава стойност. За начало е по-лесно да прочетем израза а получава стойност 5, за да сме сигурни, че лявата страна получава стойността на дясната! По същия начин въвеждаме b:=3
3) Питаме a>b, еквивалентно на 5>3 - отговорът е ДА
4) Извеждаме а
5) Край на програмата

Нашият алгоритъм работи - БРАВО!

Както казах по-горе обаче има случай, в зависимост от условието на задачата, която трябва да решим, когато този алгоритъм няма да работи. Какво ще стане ако въведем a:=5 и b:=5?

По настоящия алгоритъм условният блок ще даде резултат НЕ и ще изпишем b, чиято стойност е 5. Ами ако целта е не само да изведем число, а да "върнем" резултат самата променлива a или b? По настоящия алгоритъм ще имаме резултат b, което обаче може и да не е по-голямото a => нашият алгоритъм не изпълнява коректно задачата си.

Ето едно възможно решение:
След като сравним a и b, в случай, че a>b върне резултат НЕ правим още една проверка b>a. Ако блокът ни върне резултат ДА - извеждаме b. Ако блокът ни върне резултат НЕ следва, че двете числа са равни и извеждаме (например) "Числата са равни". Можете ли сами да направите съответната блок-схема?


Стана ли ясно? Надявам се, че да! Това е всичко за днес :) В следващият урок ще разменяме стойностите на две променливи, може би ще видим какво са циклите и за какво ги използваме. До тогава затвърди знанията си дотук и се опитай да изпълниш следните задачи:

1) Измисли алгоритъм за намиране на най-голямото от три числа, реализирай неговата блок схема. Можеш ли да разгледаш и специалния случай, когато числата са равни?
2) Направи ли задача 1? Да, значи е време за алгоритъм за намиране на най-голямото от четири числа. Струва ти се трудно или невъзможно? Има и по-лесен начин, за който ще си говорим другия път, но все пак опитай, за да се убедиш защо трябва да използваш този "по-лесен начин".
3) Въведи две числа. Ако те са равни, въведи трето число и изпиши всички числа. Ако не са - изведи първото въведено число.

УСПЕХ!

За блога и създателя му

ЗА МЕН:

Здравейте! Като ученик на Технологично училище Електронни системи се занимавам с програмиране. В началото, още преди да започнем часовете по програмиране в училище, ми беше много трудно да започна - да, в интернет има хиляди уроци, особено за начинаещи, но те всички започват с програма Hello World, независимо на кой език за програмиране се учим, а след това се преминава към "същинско програмиране". Важното, обаче е преди това да се научим на алгоритми - нещо, което е абсолютно задължително в програмирането, да се научим да създаваме и използваме алгоритми, чийто решения вече могат да се пишат на най-различни езици. Поради "по-голямата липса" на подобна информация в интернет - особено на български език - , реших и аз да допринеса за развитието на програмната наука в България - до колкото ми е възможно - . Цялата информация, която живот и здраве ще се публикува, щеше да е недостъпна за мен без ТУЕС, затова всички трябва да сме благодарни за съществуването на училището!

Преди да започнем искам да изясня няколко неща:
- всички уроци са главно с ПРАКТИЧЕСКА ЦЕЛ и по-малко теоретична
- уроците, които са ориентирани към практическото програмиране, ще се пишат на програмния език С
- този блог е НЕОФИЦИАЛЕН и всички грешки, допуснати в него, са по вина на създателя и неговото незнание, а не на Технологичното у-ще!!!

Ами... ДА ЗАПОЧВАМЕ!