161

Rekurencyjna i iteracyjna realizacja ciągu Fibonacciego

8195322-a-perfect-and-amazing-fibonacci-pattern-in-a-nautilus-shellCzłowiek od dawna dążył do znalezienia opisu ideału. Jednym z pomysłów opisu jest ciąg Fibonacciego, zwanego inaczej Złotym Podziałem.

Zajmiemy się tutaj implementacją kodu obliczającego kolejne wyrazy ciągu Fibonacciego dwoma metodami.

Zanim przejdziemy do realizacji programowej, zapoznajmy się z odrobiną teorii. Ciąg Fibonacciego można opisać wzorem ogólnym:

\ F_{n} = 0, dla n=0,

\ F_{n} = 1, dla n=1,

\ F_{n} = F_{n-1}+F_{n-2}, dla n>1,

Czyli nasze kolejne wyrazy ciągu dla n=8 wynosi:

\ F_{8} = (0,1,1,2,3,5,8,13)

Tyle teorii nam wystarczy. Po większą dawkę wiedzy na ten temat odsyłam do źródeł zewnętrznych.

Przejdziemy teraz to programu. Głównym celem programu jest wydruk liczb ciągu Fibonacciego w zakresie osiągalnych liczb całkowitych. Program posiada opcję wyboru metody przebiegu algorytmu – rekurencyjnie lub iteracyjnie. Idzie za tym inna forma wyświetlania wyniku. Rekurencyjny – użytkownik podaj numer interesującego go wyrazu ciągu. Iteracyjny – wyniki są wyświetlane w formie tablicy, użytkownik wybiera ile wyrazów ciągu ma zawierać tablica. Użytkownik ma prawo wyboru poprzez menu. Przypomnijmy czym jest rekurencja i iteracja oraz czym się różnią.

Iteracja – jest to czynność powtarzania tej samej czynności określoną ilość razy np. w pętlach.

Rekurencja – jest to odwoływanie się naszej napisanej funkcji do samej siebie.

Pierwszym blokiem programowym jest menu użytkownika:

int choice;
    do {
            printf("Podaj opcje: \n1 - obliczanie n-tego wyrazu fibbonaciego \n");
            printf("2 - wypisanie pierwszych n wyrazow \n");
            printf("0 - wyjdz\n\n");
            scanf("%d", &choice);
            if(choice == 1)

Mówiłem wcześniej, że zależy nam na jak największym zasięgu naszego programu. Właśnie dla tego pojawia się tutaj kolejny blok programu:

#include <stdio.h>
#include <stdlib.h>
typedef unsigned long long int ULLI;

Zadeklarowane tu zostały dwie najczęściej stosowane biblioteki oraz globalna zmienna ULLI (skrót od unsigned long long int).

Element typedef pozwala zamienić stosowanie wyrazu int na ULLI. Poprawia to znacznie klarowność kodu oraz ułatwia pracę.

Element unsigned pozwala mi przesunąć zakres typu int w stronę liczb dodatnich. Jest to korzystne gdyż korzystamy z liczb całkowitych dodatnich. Poprawia to znaczenie zasięg i moc algorytmu. Konkretniej mówiąc pozwala mi to wykorzystać 64 bity przypisane dla typu long long int w stronę operatorów ciągu tj. z zakresu −9 223 372 036 854 775 808 — +9 223 372 036 854 775 807, do zakresu 0 — +18 446 744 073 709 551 615.

Omówimy teraz część rekurencyjną kodu:

ULLI fib(int n)
{
    if (n == 0)
        return 0;
    else if (n == 1)
        return 1;
    else
        return fib(n-1)+fib(n-2);
}

Niestety… Aby zrozumieć rekurencję, trzeba zrozumieć rekurencję. Ale zastosowany powyżej algorytm opisuje rysunek:

CCF20130513_00000

Jest to typowa rekurencja. Algorytm działa po przez dodawane kolejnych wyrazów. Dodaje on dwa składniki bazowe a potem dodaje powielenie.

Ten segment programu wykazuje się błędem podczas podania przez użytkownika innego znaku niż cyfra. Objawia się to zawieszeniem programu. Przy podaniu liczby ujemnej program powraca do wyboru metody obliczeniowej. Skuteczne i szybkie obliczenia można otrzymać do ok. 43 wyrazu ciągu. Jest to spowodowane specyfikacją metody rekurencji (ilość dodawań) oraz możliwościami hardwareowymi.

Metoda iteracyjna:

void print_fib(int n)
{
    ULLI a = 0;
    ULLI b = 1;
    ULLI c = a+b;
    int i;

    for(i = 1; i <= n; i++)
    {
        printf("%i %llu\n", i, c);
        c = a+b;
        a=b;
        b=c;

    }
    printf("\n");
}

 

Na początku deklarowane są zmienne typu int pod nazwą ULLI. Są to zmienne lokalne. Pętla for pobiera i=1, sprawdza warunek i zwiększa i o jeden. Printf wyświetla numer wyrazu i obliczony wyraz zgodnie z zastosowaną arytmetyką.

Tak samo jak w poprzedniej metodzie wprowadzenie liczy ujemnej powoduje powrót do menu. Wprowadzenie innego znaku niż liczba powoduje zapętlenie algorytmu na jednym wyrazie ciągu lub zapętla się w nieskończoność. Obliczenia są prawidłowe do 93 wyrazu ciągu włącznie. Dalej następuje koniec zakresu i podanie fałszywych wartości.

Zachęcam do doczytania odnośnie Złotego Podziału. Jak widzicie jest to całkiem ciekawy temat, który można opisać za pomocą nieskomplikowanego kodu. Na zakończenie podaję kod całościowy:

#include <stdio.h>
#include <stdlib.h>
typedef unsigned long long int ULLI;



ULLI fib(int n)
{
    if (n == 0)
        return 0;
    else if (n == 1)
        return 1;
    else
        return fib(n-1)+fib(n-2);
}

void print_fib(int n)
{
    ULLI a = 0;
    ULLI b = 1;
    ULLI c = a+b;
    int i;

    for(i = 1; i <= n; i++)
    {
        printf("%i %llu\n", i, c);
        c = a+b;
        a=b;
        b=c;

    }
    printf("\n");
    //max is fib(93)
}

void info()
{
    printf("Radoslaw Sakowicz\n");
    printf("www.uengineering.net\n\n");
    printf("Rekurencyjne obliczanie liczb Fibonacciego.\n\n");
}

int main()
{

    info();

    int choice;
    do {
            printf("Podaj opcje: \n1 - obliczanie n-tego wyrazu fibbonaciego \n");
            printf("2 - wypisanie pierwszych n wyrazow \n");
            printf("0 - wyjdz\n\n");
            scanf("%d", &choice);
            if(choice == 1)
            {
                int n;

                do {
                    printf("Podaj numer wyrazu (liczba ujemna - koniec obliczen), n = ");
                    scanf("%d", &n);
                    if(n < 0)
                        break;
                    printf("(%d) = %d\n\n", n, fib(n));
                } while(1);

            }
            else if(choice == 2)
            {
                int n;
                do {
                    printf("Podaj ile wyrazow chcesz poznac (liczba ujemna - koniec obliczen): \n\n");
                    scanf("%d", &n);
                    print_fib(n);

                } while (n >= 0);
            }
            else if(choice == 0)
            {
                break;
            }


    } while(1);

    scanf("%c");
    return 0;
}

 

Radosław Sakowicz

Student Automatyki i Robotyki na Wydziale Mechanicznym Politechniki Białostockiej. Z zamiłowania płetwonurek. Zainteresowania: Programowanie w środowisku Matlab oraz C/C++, elektronika, mechanika

161 Comments

  1. Pingback: A片
  2. Pingback: meriking
  3. Pingback: stromectol 6 mg
  4. Pingback: madridbet
  5. Pingback: meritking
  6. Pingback: propecia 1mg buy
  7. Pingback: grandpashabet
  8. Pingback: grandpashabet
  9. Pingback: fuck google
  10. Pingback: fuck google
  11. Pingback: madridbet
  12. Pingback: meritking
  13. Pingback: meritking giriş
  14. Pingback: grandpashabet
  15. Pingback: meritking
  16. Pingback: izmir escort
  17. Pingback: child porn
  18. Pingback: xxlargeseodigi
  19. Pingback: porn
  20. Pingback: porn
  21. Pingback: porn
  22. Pingback: porn
  23. Pingback: sex
  24. Pingback: izmir travesti
  25. Pingback: gaziemir escort
  26. Pingback: fethiye escort
  27. Pingback: eyüpsultan escort
  28. Pingback: etiler escort
  29. Pingback: hd porno izle
  30. Pingback: istanbul travesti
  31. Pingback: porn
  32. Pingback: kralbet
  33. Pingback: yasam ayavefe
  34. Pingback: grandpashabet
  35. Pingback: grandpashabet
  36. Pingback: grandpashabet
  37. Pingback: child porn
  38. Pingback: porna
  39. Pingback: travesti.site
  40. Pingback: animal porn
  41. Pingback: porn
  42. Pingback: child porn
  43. Pingback: vassycalvados.fr
  44. Pingback: child porn
  45. Pingback: child porn
  46. Pingback: jojobet
  47. Pingback: jojobet twitter
  48. Pingback: animal porn
  49. Pingback: ananın amı
  50. Pingback: child porn
  51. Pingback: meritking
  52. Pingback: child porn
  53. Pingback: child porn
  54. Pingback: spinco
  55. Pingback: iyibilirdik
  56. Pingback: porn
  57. Pingback: Cocuk pornosu
  58. Pingback: child porn
  59. Pingback: betine giris
  60. Pingback: bursa travesti
  61. Pingback: child porn
  62. Pingback: bmw
  63. Pingback: kadinlar
  64. Pingback: spam
  65. Pingback: porn
  66. Pingback: bugatti tumblr
  67. Pingback: ankara travesti
  68. Pingback: edebiyat tumblr
  69. Pingback: ankaratravesti.xyz
  70. Pingback: child porn
  71. Pingback: child porn
  72. Pingback: child porn
  73. Pingback: sex
  74. Pingback: iporn
  75. Pingback: porn
  76. Pingback: porn
  77. Pingback: rize tumblr
  78. Pingback: meritking
  79. Pingback: porn
  80. Pingback: gece tumblr
  81. Pingback: sakakrizi tumblr
  82. Pingback: child porn
  83. Pingback: inovapin.com
  84. Pingback: porn
  85. Pingback: porn
  86. Pingback: spam
  87. Pingback: Konya Seo Uzmanı
  88. Pingback: biznes kniga
  89. Pingback: child porn
  90. Pingback: child porn
  91. Pingback: child porn
  92. Pingback: child porn
  93. Pingback: child porn
  94. Pingback: porn
  95. Pingback: ankara psikolog
  96. Pingback: child porn
  97. Pingback: porn
  98. Pingback: child porn watch
  99. Pingback: hardcore porn
  100. Pingback: meritking
  101. Pingback: meritking giriş
  102. Pingback: meritking gir
  103. Pingback: meritking news
  104. Pingback: silivri avukat
  105. Pingback: porn
  106. Pingback: porn
  107. Pingback: hd porn
  108. Pingback: child porn
  109. Pingback: hp servis izmir
  110. Pingback: porn
  111. Pingback: child porn
  112. Pingback: child porn
  113. Pingback: grandpashabet
  114. Pingback: cenforceindia.com
  115. Pingback: canlı maç izle
  116. Pingback: vardenafilotc.com
  117. Pingback: ivermectino.com
  118. Pingback: zithromaxotc.com
  119. Pingback: google fuck
  120. Pingback: child porn
  121. Pingback: porn
  122. Pingback: child porn
  123. Pingback: child porn
  124. Pingback: porn
  125. Pingback: spam
  126. Pingback: child porn