Schemat Hornera jest sposobem obliczania wartości wielomianu dla podanego argumentu. Dzięki tej metodzie ograniczamy liczbę mnożeń, którą musimy wykonać w celu rozwiązania problemu. W tym materiale zaimplementujemy w języku C++ dwie wersje algorytmu: iteracyjną oraz rekurencyjną.

Specyfikacja problemu:

Dane:

  • wspolczynniki[] – tablica zawierająca liczby rzeczywiste (kolejne współczynniki wielomianu)

  • stopienWielomianu – liczba naturalna

  • x – liczba rzeczywista; argument, dla którego obliczana jest wartość wielomianu

Wynik:

  • wynik – liczba rzeczywista

Przykładowe wyjście:

Linia 1. Wartość wielomianu dla argumentu x znak równości 4.

Schemat Hornera – wersja iteracyjna

Zapiszmy krok po kroku algorytm obliczający wartość wielomianu w wersji iteracyjnejiteracjaiteracyjnej.

Krok 1.

Zapiszmy nagłówek naszej funkcji.

Najpierw zapisujemy typ zwracanych wartości przez naszą funkcję. W tym przypadku może to być zarówno typ int, float, double, jak i void. W przypadku funkcji typu void musimy w ciele funkcji zawrzeć wypisywanie na ekran obliczonej wartości.

Następnie zapisujemy nazwę naszej funkcji horner, a potem w okrągłych nawiasach zapisujemy argumenty funkcji. Pierwszym z argumentów jest tablica wspolczynniki zawierająca, jak sama nazwa wskazuje, wszystkie współczynniki znajdujące się przy kolejnych potęgach naszego wielomianu. Kolejnym argumentem jest stopienWielomianu. Jest to zmienna, w której przechowywana jest największa potęga naszego wielomianu. Ostatnim argumentem jest zmienna x. Jest to argument, dla którego będziemy obliczać wartość wielomianu.

Linia 1. int hornerIteracyjnie otwórz nawias okrągły int wspolczynniki otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopienWielomianu przecinek int x zamknij nawias okrągły.

Krok 2.

Deklarujemy zmienną wynik. Może być ona zarówno typu int, double, jak i float.

Linia 1. int wynik średnik.

Krok 3.

Kolejnym krokiem będzie przypisanie do zmiennej wynik wartości równej wyrazowi wolnemu w naszym wielomianie.

Linia 1. wynik znak równości wspolczynniki otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik.

Krok 4.

Następnie tworzymy pętlę wykonującą się od i = 1 do i = stopienWielomianu. Zaczynamy pętlę od wartości równej 1, ponieważ wartość współczynnika wyrazu wolnego została uwzględniona w obliczeniach poza pętlą. Pętla wykonuje się do wartości równej stopienWielomianu, ponieważ zaczynamy od stopnia równego 1 i wykonujemy pętlę do momentu, w którym obliczymy cały wielomian.

Linia 1. for otwórz nawias okrągły int i znak równości 1 średnik i otwórz nawias ostrokątny znak równości stopienWielomianu średnik i plus plus zamknij nawias okrągły.

Krok 5.

W pętli do zmiennej wynik przypisujemy jej obecną wartość przemnożoną przez argument x, a do tego dodajemy zmienną zapisaną w tabeli wspolczynniki pod indeksem i.

Linia 1. wynik znak równości wynik asterysk x plus wspolczynniki otwórz nawias kwadratowy i zamknij nawias kwadratowy średnik.

Krok 6.

Po wykonaniu pętli dla funkcji typu void wypisujemy wartość zmiennej wynik w odpowiednim komunikacie.

Linia 1. cout otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów Wartość wielomianu dla argumentu x znak równości cudzysłów otwórz nawias ostrokątny otwórz nawias ostrokątny wynik średnik.

Dla funkcji typu całkowitego (int) zwracamy zmienną wynik

Linia 1. return wynik średnik.

Cały algorytm, włącznie z krokiem 6. zapisanym dla funkcji typu całkowitego, prezentuje się następująco:

Linia 1. int hornerIteracyjnie otwórz nawias okrągły int wspolczynniki otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopienWielomianu przecinek int x zamknij nawias okrągły. Linia 2. otwórz nawias klamrowy. Linia 3. int wynik znak równości wspolczynniki otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik. Linia 5. for otwórz nawias okrągły int i znak równości 1 średnik i otwórz nawias ostrokątny znak równości stopienWielomianu średnik i plus plus zamknij nawias okrągły. Linia 6. wynik znak równości wynik asterysk x plus wspolczynniki otwórz nawias kwadratowy i zamknij nawias kwadratowy średnik. Linia 8. return wynik średnik. Linia 9. zamknij nawias klamrowy.

Sprawdźmy jego działanie dla przykładowych danych. Przetestujemy działanie programu dla następującego wielomianu:

W(x) = x2 + 3x - 6

oraz x = 2.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. using namespace std średnik. Linia 4. int hornerIteracyjnie otwórz nawias okrągły int wspolczynniki otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopienWielomianu przecinek int x zamknij nawias okrągły. Linia 5. otwórz nawias klamrowy. Linia 6. int wynik znak równości wspolczynniki otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik. Linia 8. for otwórz nawias okrągły int i znak równości 1 średnik i otwórz nawias ostrokątny znak równości stopienWielomianu średnik i plus plus zamknij nawias okrągły. Linia 9. wynik znak równości wynik asterysk x plus wspolczynniki otwórz nawias kwadratowy i zamknij nawias kwadratowy średnik. Linia 11. return wynik średnik. Linia 12. zamknij nawias klamrowy. Linia 14. int main otwórz nawias okrągły zamknij nawias okrągły. Linia 15. otwórz nawias klamrowy. Linia 16. int wspolczynniki otwórz nawias kwadratowy zamknij nawias kwadratowy znak równości otwórz nawias klamrowy 1 przecinek 3 przecinek minus 6 zamknij nawias klamrowy średnik. Linia 17. int stopienWielomianu znak równości 2 średnik. Linia 18. int x znak równości 2 średnik. Linia 19. cout otwórz nawias ostrokątny otwórz nawias ostrokątny hornerIteracyjnie otwórz nawias okrągły wspolczynniki przecinek stopienWielomianu przecinek x zamknij nawias okrągły średnik. Linia 21. return 0 średnik. Linia 22. zamknij nawias klamrowy.

Program na wyjściu daje liczbę 4, co jest poprawnym wynikiem.

Schemat Hornera – wersja rekurencyjna

Zapiszmy, krok po kroku, algorytm schematu Hornera w wersji rekurencyjnejrekurencjarekurencyjnej.

Krok 1.

Zapiszmy nagłówek naszej funkcji:

Linia 1. int hornerRekurencyjnie otwórz nawias okrągły int wspolczynniki otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopienWielomianu przecinek int x zamknij nawias okrągły.

Składa się on z następujących elementów:

  • typu zwracanych wartości przez funkcję – w tym przypadku może to być zarówno int, float, jak i double,

  • nazwy funkcji hornerRekurencyjnie,

  • argumentów funkcji zapisanych w okrągłych nawiasach.

Pierwszym z argumentów jest tablica wspolczynniki zawierająca wszystkie współczynniki znajdujące się przy kolejnych potęgach naszego wielomianu. Kolejnym argumentem jest stopienWielomianu. Jest to zmienna, w której przechowywana jest największa potęga naszego wielomianu. Ostatnim argumentem jest zmienna x. Jest to argument, dla którego będziemy obliczali wartość wielomianu.

Krok 2.

Kolejnym krokiem jest ustalenie warunku przerwania rekurencji. Tym warunkiem będzie to, czy zmienna stopienWielomianu jest równa 0.

Linia 1. if otwórz nawias okrągły stopienWielomianu znak równości znak równości 0 zamknij nawias okrągły.

Krok 3.

Jeśli warunek zapisany w kroku 2 jest spełniony, zwracamy współczynnik z indeksem zero – jest to wyraz wolny naszego wielomianu.

Linia 1. return wspolczynniki otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik.

Krok 4.

Jeśli nasz warunek nie jest spełniony, zwracamy argument, dla którego obliczamy wartość wielomianu pomnożoną przez wartość, jaką zwróci nam wywołana rekurencyjnie funkcja hornerRekurencyjnie() z argumentami wspolczynniki, stopienWielomianu - 1, x oraz dodanym współczynnikiem zapisanym pod indeksem stopienWielomianu.

Linia 1. return x asterysk hornerRekurencyjnie otwórz nawias okrągły wspolczynniki przecinek stopienWielomianu ‑ 1 przecinek x zamknij nawias okrągły plus wspolczynniki otwórz nawias kwadratowy stopienWielomianu zamknij nawias kwadratowy średnik.

Algorytm obliczający wartość wielomianu zapisany w wersji rekurencyjnej zaimplementowany w języku C++ wygląda następująco:

Linia 1. int hornerRekurencyjnie otwórz nawias okrągły int wspolczynniki otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopienWielomianu przecinek int x zamknij nawias okrągły. Linia 2. otwórz nawias klamrowy. Linia 4. if otwórz nawias okrągły stopienWielomianu znak równości znak równości 0 zamknij nawias okrągły. Linia 5. return wspolczynniki otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik. Linia 6. else. Linia 7. return x asterysk hornerRekurencyjnie otwórz nawias okrągły wspolczynniki przecinek stopienWielomianu minus 1 przecinek x zamknij nawias okrągły plus wspolczynniki otwórz nawias kwadratowy stopienWielomianu zamknij nawias kwadratowy średnik. Linia 8. zamknij nawias klamrowy.

Sprawdźmy jego działanie dla przykładowych danych. Przetestujemy działanie programu dla następującego wielomianu:

W(x) = x2 + 3x - 6

oraz x = 2.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. using namespace std średnik. Linia 4. int hornerRekurencyjnie otwórz nawias okrągły int wspolczynniki otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek int stopienWielomianu przecinek int x zamknij nawias okrągły. Linia 5. otwórz nawias klamrowy. Linia 7. if otwórz nawias okrągły stopienWielomianu znak równości znak równości 0 zamknij nawias okrągły. Linia 8. return wspolczynniki otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik. Linia 9. else. Linia 10. return x asterysk hornerRekurencyjnie otwórz nawias okrągły wspolczynniki przecinek stopienWielomianu minus 1 przecinek x zamknij nawias okrągły plus wspolczynniki otwórz nawias kwadratowy stopienWielomianu zamknij nawias kwadratowy średnik. Linia 11. zamknij nawias klamrowy. Linia 13. int main otwórz nawias okrągły zamknij nawias okrągły. Linia 14. otwórz nawias klamrowy. Linia 15. int wspolczynniki otwórz nawias kwadratowy zamknij nawias kwadratowy znak równości otwórz nawias klamrowy 1 przecinek 3 przecinek minus 6 zamknij nawias klamrowy średnik. Linia 16. int stopienWielomianu znak równości 2 średnik. Linia 17. int x znak równości 2 średnik. Linia 18. cout otwórz nawias ostrokątny otwórz nawias ostrokątny hornerRekurencyjnie otwórz nawias okrągły wspolczynniki przecinek stopienWielomianu przecinek x zamknij nawias okrągły średnik. Linia 20. return 0 średnik. Linia 21. zamknij nawias klamrowy.

Program na wyjściu daje liczbę 4, co jest poprawnym wynikiem.

Słownik

algorytm
algorytm

przepis postępowania prowadzący do rozwiązania ustalonego problemu, określający ciąg czynności elementarnych, które należy w tym celu wykonać

iteracja
iteracja

technika programowania polegająca na powtarzaniu tych samych operacji w pętli określoną liczbę razy lub do momentu, aż zostanie spełniony zadany warunek

przypadek podstawowy
przypadek podstawowy

przypadek, dla którego funkcja rekurencyjna nie wywołuje samej siebie, a zamiast tego zwraca z góry określoną wartość

rekurencja
rekurencja

technika programowania polegająca na tym, że funkcja wywołuje samą siebie, aż do napotkania przypadku podstawowego

stopień wielomianu
stopień wielomianu

najwyższa potęga przy zmiennej, która nie jest równa zero

wielomian
wielomian

wyrażenie algebraiczne będące sumą jednomianów, czyli wyrażeń postaci aIndeks dolny nxIndeks górny n

William George Horner
William George Horner

brytyjski matematyk żyjący w latach 1786–1837; w wieku 14 lat został asystentem nauczyciela w szkole w Bristolu, a w 1809 roku założył własną szkołę w Bath; podał sposób wyznaczania wartości wielomianu z wykorzystaniem minimalnej liczby operacji możenia

wykonanie elementarne w rekurencji
wykonanie elementarne w rekurencji

moment, gdy funkcja rekurencyjna zwraca konkretną wartość zamiast kolejnego wywołania rekurencyjnego