Кога се обидуваме да решиме некој проблем со помош на компјутерска програма, се трудиме да го разделиме проблемот на помали делови, потпроблеми кои се полесни за решавање. Кога потпроблемот е ист како и главниот, но на помало множество податоци, велиме дека проблемот е дефиниран рекурзивно.
латински: re = назад + currere = извршува;
Проблем : Отворање руски кукли (Матрјошки)
Замислете дека имате збир од кукли Матрјошки поставени една во друга, и барате златно прстенче што се наоѓа во најмалата кукла.Базен случај (Услов за прекин): Ја отворате тековната кукла и проверувате дали внатре е прстенчето (или дали куклата е празна/нема повеќе кукли внатре). Ако ја најдете саканата кукла со прстенчето, застанувате и го земате.
Рекурзивен чекор: Ако куклата е празна но во неа има помала кукла, ја отворате помалата кукла и го повторувате истиот процес (се повикувате себеси за следната, помала кукла).
Дефиниција Рекурзија
Заклучуваме:
Значи :
Клучни елементи на секоја рекурзија
рекурзивна функција за пресметка на факториел
int factorial(int N){
if (N <= 1) //N==0 || N==1
return 1; //(0!)=1,(1!)=1, po definicija
else
return N * factorial(N-1);//rekurziven povik
}
Кога функција повикува друга функција, програмата мора да запомни каде треба да продолжи по завршувањето на повиканата функција.
За тоа се користи стекот на повикувања (call stack).
Кај рекурзијата, секое ново повикување создава нова рамка на стекот. Кога ќе се достигне базниот случај, повиците почнуваат да се враќаат наназад
Што прави: Го става новиот елемент на самиот врв на стегот.
Како функционира во пракса: Исто како кога ќе земеш чинија и ќе ја ставиш најгоре на веќе постоечките чинии во кутијата. Тој нов елемент сега стапнува на врвот и прв ќе биде достапен.
Во програмирањето (рекурзијата): Секогаш кога функцијата ќе се повика самата себе, компјутерот прави push на новиот мемориски блок (Stack Frame) на системскиот стог.
Што прави: Го отстранува и го враќа елементот што се наоѓа на самиот врв на стегот.
Како функционира во пракса: Исто како кога ја земаш најгорната чинија од кутијата за да ја користиш. Не можеш да ја извадиш таа од средината или од дното додека не ги тргнеш сите над неа.
Во програмирањето (рекурзијата): Кога рекурзивната функција ќе го стигне базниот случај (return), таа се брише од меморијата — компјутерот прави pop на тој мемориски блок и се враќа назад на претходната задача.
Клучна филозофија на стегот: LIFO
Стегот работи по принципот LIFO (Last In, First Out — Последен влегува, прв излегува). Оние елементи што последно сме ги ставиле (push), први мора да ги тргнеме (pop).
Итерација е постапка на извршување на низа инструкции се додека е исполнет претходно зададен услов. Изразот итерација вклучува иницијализација, споредување, извршување на наредби во самиот циклус и конечно ажурирање на контролната варијабла.
По ажурирањето на контролната варијабла, се повторува постапката се додека условот во итерацискиот израз е вистинит. 3 видови структури за повторување се "for", while, "do-while".
#include <iostream>using namespace std;int factorial1(int n){ int r = 1; for (int i=2; i<=n; i++) r = r*i; return r;}int factorial2(int n){ if (n <= 1) //n==0 || n==1 return 1; //(0!)=1, (1!)=1 return n * factorial2(n-1); //rekurziven povik}int main(){ cout << factorial1(5) << endl; //120 cout << factorial2(5) << endl; //120 return 0;}int stepen(int x, int n)
{
if(n==1)
return 1;
else
return x*stepen(x,n-1) ;
}
int main() {
int XN,X,N;
cin >> X; cin >> N;
XN=stepen(X,N);
cout << XN << endl;
return 0;
}
Задачи
1.Дополни
#include <iostream>
using namespace std;
int faktoriel(int n) {
// 1. Базен случај (услов за прекин на рекурзијата)
if (n == 0 || n == 1) {
return ____________; // Ученикот го допишува точниот резултат
}
// 2. Рекурзивен чекор
return n * faktoriel(____________); // Ученикот ја менува вредноста во повикот
}
int main() {
int broj = 5;
cout << "Faktorielot e: " << faktoriel(broj) << endl;
return 0;
}
Колку пати ќе се повика функцијата faktoriel ако внесеме broj = 4?
- функција main
- почетна вредност ма променливата во for циклусот
- условот кој ја прекинува рекурзијата и спречува бесконечно повикување
- итерацијата користи константна меморија, додека рекурзијата зезема нов простор на стекот за
- рекурзијата троши помалку меморија бидејќи не користи променливи
- програмата ќе падне поради прелевање на стекот (stack overflow)
- програмата ќе заврши со вредност 0
- ќе се испечати само првиот член
No comments:
Post a Comment