Napíšte rekurzívnu procedúru, ktorá pri vstupe čísla n , znakoch a,b,c vypíše. a n c bn (vypíše sa n-krát a potom c a potom n-krát b).
Riešenie:
- Podľa zadania, ak napríklad n=3, tak procedúra by mala vypísať aaacbbb. Ak sa pozrieme na tento reťazec, tak vidíme, že slovo je symetrické. Teda, ak by sme zo začiatku a z konca zobrali po
jednom
znaku, tak by sme dostali podobný znak, teda podproblém nižšieho stupňa.
Ak by sme mali vypísať len acb, procedúra by vyzerala takto:
procedure vypis1(a,b,c:string); |
begin |
|
write(a); |
|
write(c); |
|
write(b); |
end; |
- Táto procedúra je dobrá len pre prípad n=1. Vieme, že sa musia znaky a a b vypísať n krát. Teda ak namiesto príkazu write(c) napíšeme príkaz volania tej istej procedúry, tak sa bude vykonávať znovu tá
istá procedúra (čo vlastne potrebujeme).
procedure vypis(a,b,c:string); |
begin |
|
write(a); |
|
procedure vypis(a,b,c); |
|
write(b); |
end; |
- Takto upravená procedúra nám bude vypisovať len reťazec a, pretože nemáme podmienku ukončenia rekurzívneho vnárania. Keďže máme príkaz aj po rekurzívnom volaní a tie sa vykonávajú pri rekurzívnom vynáraní, potrebujeme dobru podmienku ukončenia vnárania. Vieme, že znak a sa má vypísať n krát. Tak pridáme ešte jeden parameter procedúre a pri príkaze volania procedúry sa bude znižovať o jedno. Potrebujeme ešte niekde vypísať reťazec c. Ten však potrebujeme vypísať ešte pred reťazcom b (ten sa vypisuje pri vynáraní). Jediná možnosť kedy sa dá vypísať iba raz je, ak nie je splnená podmienka rekurzívneho vnárania vo vetve else. Podmienka ukončenia bude ak n>0, tak rob inak vypíš reťazec c.
Doplnená procedúra:
procedure vypis(a,b,c:string; n:integer); |
begin |
|
if n>0 then |
|
begin |
|
|
write(a); |
|
|
procedure vypis(a,b,c,n-1); |
|
|
write(b); |
|
end; |
|
else write(c); |
end; |
Takto definovaná procedúra bude vypisovať a pokiaľ n>0. Ak n=0, tak vypíše c a potom sa bude pri vynáraní
vypisovať b. |