rekurzívne funkcie

Príklad 2

Napíšte rekurzívnu funkcie na výpočet ciferného súčet čísla A.

Riešenie:

  1. Funkcia má vrátiť ciferný súčet zadaného čísla, teda jej návratový typ bude celé číslo.
    Parametrom funkcie je číslo, keďže to môže byť viacciferné číslo, tak je parameter bude longint.
    Názvom funkcie bude cifsucin.
    Teda zatiaľ "prázdna" funkcia bude vyzerať takto:

    function cifsucet(n:longint):integer;
    begin
    .....
    end;

  2. Ak máme číslo 123, tak ciferný súčet tohto čísla je 1+2+3=6. Keďže je potrebné vytvoriť rekurzívnu funkciu, musíme nájsť problém, ktorý sa dá rozložiť na menšie problémy rovnakého typu. Ciferný súčet môžme rozdeliť na časti 3+ (ciferný súčet čísla 12), a ten môžme rozdeliť na 2+ (ciferný súčet čísla 1).

    Ak takto rozdelíme problém súčtu na menšie problémy, tak potrebujeme zistiť poslednú cifru čísla. To zistíme pomocou funkcie MOD 10 (táto funkcia nám vráti zvyšok po delení 10 zadaného čísla). Keďže nám táto funkcia vráti číslo, tak ho môžme hneď použiť a nemusíme si na uchovanie jeho hodnoty deklarovať navyše premennú. Vieme, že toto číslo priradíme funkcií a ešte niečo v súčte...

    function cifsucet(n:longint):integer;
    begin
      cifsucin:=(n mod 10)i+...
    end;

  3. Ak úž pripočítame poslednú cifru, tak potrebujeme vypočítať ciferný súčet iba z čísla o túto cifru kratšieho. Na "odrezanie" posledného čísla použijeme funkciu DIV 10 (táto funkcia vráti číslo, ktoré je výsledkom celočíselného delenia 10). Funkcia vracia čísla, takže ju môžme použiť ako parameter pri volaní tej istej funkcie. Teda:

    function cifsucet(n:longint):integer;
    begin
      cifsucin:=(n mod 10)+cifsucin (n div 10);
    end;


  4. Táto funkcia sa nám bude vnárať, ale nikdy vynárať, potrebujeme doplniť podmienku rekurzívneho vnárania. S touto podmienkou súvisí aj dno rekurzívneho vnárania. Dno je príkaz, ktorý sa vykoná, ak podmienka rekurzívneho vnárania nie je splnená a v tomto príkaze sa musí funkcií priradiť nejaká konštantná hodnota (reťazec, číslo,...).

    Vieme, že číslo delíme 10 a používame jeho podiel aj zvyšok. Toto však môžme robiť len z číslami viaccifernými. Ak číslo je dvojciferné napríklad 21, tak vo funkcií urobíme cifsucin:=1+cifsucin(2). A vo volaní cifsucin(2) nastáva problém, tu už nepotrebujeme robiť delenie 10, pretože sme na konci čísla a potrebujeme už len jeho hodnotu. Ako číslo je jednociferné, tak sa funkcií priradí jeho hodnota a ak je viacciferné, tak sa vykoná príkaz priradenia rekurzívneho volania funkcie. Upravená funkcia vyzerá takto:


    function cifsucet(n:longint):integer;
    begin
      if n>=10 then
        cifsucin:=(n mod 10)+cifsucin (n div 10);
      else cifsucin:=n;
    end;
  5. Ak n=456 tak: cifsucet(456)=6+cifsucet(45)=6+(5+cifsucet(4))=6+(5+4))=6+9=15

     

Funkciu môžme zavolať napríklad príkazom cifsucet(123450)