rekurzívne funkcie

Príklad 4

Zbojníci používajú zašifrovaný jazyk, v ktorom sa niektoré písmena zdvoja a medzi vzniknutú dvojicu sa vloží hláska o. Napíšte rekurzívnu funkciu na odšifrovanie zbojníckej správy.

Riešenie:

  1. Začneme tak, ako v predchádzajúcich príkladoch:
    Názov funkcie bude sifra.
    Jej parameter bude reťazec, keďže šifrujeme slová.
    Návratový typ funkcie je reťazec.


    function sifra(s:string):string;
    begin
      . . .
    end;

  2. Vieme, že niektoré znaky sú zdvojene a niektoré nie. Našou úlohou je nájsť tie, ktoré sú zdvojené. Ak nájdeme takú trojicu ktorá zodpovedá spôsobu zašifrovania, tak vynecháme druhý a tretí znak a hľadáme ďalej. Na základe tejto analýzy sme prišli na rozdelenie veľkého problému na podproblémy. Ak prvý znak je rovnaký ako tretí a druhý znak je rovný o, tak funkcií priradíme súčet prvého znaku a volania funkcie so zmeneným parametrom. Tento parameter sa zmení tak, že vynecháme prvé tri znaky z reťazca. Teda:

    function sifra(s:string):string;
    begin
        if(s[1]=s[3]) and (s[2]='o') then
          sifra:=s[1]+sifra(copy(s,4,length(s)-3))
    end;

  3. Takto to bude fungovať ak sa znaky budú rovnať, ale čo ak nebudú? to musíme ošetriť vo vetve else. Ak za prvý a tretí znak nebudú rovnať, tak sa funkcií priradí súčet prvého znaku a volania funkcie zo zmeneným parametrom. Tentokrát sa v parametri vynechá len prvý znak z reťazca.

    function sifra(s:string):string;
    begin
        if(s[1]=s[3]) and(s[2]='o') then
          sifra:=s[1]+sifra(copy(s,4,length(s)-3))
        else sifra:=s[1]+sifra(copy(s,2,length(s)-1));
    end;

  4. Zase sme sa dostali k otázke: do kedy sa budeme rekurzívne vnárať? Do vtedy, pokiaľ dĺžka reťazca je viac ako 2, teda 3, 4 alebo viac . Preto také číslo, lebo môže byť zašifrovaný aj posledný znak, musíme mať istotu pri porovnávaní, že existuje prvý a tretí znak, ktorý môžme porovnať. Ak je reťazec dĺžky 2 alebo 1 tak určite tieto znaky nie sú zašifrované.
    Po doplnení podmienky dostávame:

    function sifra(s:string):string;
    begin
      if length(s)>2 then
      begin
        if(s[1]=s[3]) and(s[2]='o') then
          sifra:=s[1]+sifra(copy(s,4,length(s)-3))
        else sifra:=s[1]+sifra(copy(s,2,length(s)-1));
      end
    end;

  5. Je potrebné do tejto funkcie ešte doplniť priradenie na dne rekurzívneho vnárania. Pri vnorení vždy pripočítavame prvý znak, keďže teraz nám ostali buď dva alebo 1, prípradne nič, tak funkcií priradíme všetko čo je v premennej reťazca (teda parameter funkcie)

    Výsledná funkcia je takáto:

    function sifra(s:string):string;
    begin
      if length(s)>2 then
      begin
        if(s[1]=s[3]) and(s[2]='o') then
          sifra:=s[1]+sifra(copy(s,4,length(s)-3))
        else sifra:=s[1]+sifra(copy(s,2,length(s)-1));
      end
      else sifra:=s;
    end;

Funkciu môžme zavolať takto: sifra(aoahooojoj);