Factoriali recursivi

Exemplul 1.8 demonstrează încă un alt mod de calculare a factoriali. Folosește o tehnică de programare numită recursiune. Recurgerea apare atunci când o metodă se numește sau, cu alte cuvinte, se referă recursiv la ea însăși. Algoritmul recursiv pentru calcularea factoriali se bazează pe faptul că n! este egal cu n * (n 1). Acest mod de calcul al factoriali este un exemplu clasic de recursiune. În acest caz, această tehnică nu este deosebit de eficientă, însă recursul are multe aplicații importante, iar acest exemplu demonstrează că utilizarea sa în Java este perfect legală. În acest exemplu, în loc de tipul de date int, care este un număr întreg pe 32 de biți, este utilizat un tip de date lung, care este un număr întreg pe 64 de biți. Factorii devin repede foarte mari, astfel încât capacitatea extra lungă face ca metoda factorial () să fie mai utilă.

Exemplul 1.8. Factorial2.java

* Această clasă demonstrează un mod recursiv de calculare a factoriali. acest

* Metoda se numește în mod repetat, pe baza formulei: n! = n * (n 1)! ** /

clasa publică Factorial2

statică publică lungă factorială (lungime x)

dacă (x <0) throw new IllegalArgumentException("x должен быть>= 0 ");

dacă (x <= 1) return 1; // Здесь рекурсия прекращается

altceva retur x * factorial (x 1); // Pasul de recurs - sună-te

Exemplul 1.9 prezintă o versiune îmbunătățită a exemplelor anterioare care calculează factoriali. Factorii sunt candidați ideali pentru cache, deoarece calculul lor necesită timp și, mai important, nu puteți calcula o mulțime de factoriali datorită limitărilor tipului lung de date. Prin urmare, în aceste exemple, deoarece factorialul este calculat, valoarea lui este păstrată pentru utilizare ulterioară.

În plus față de demonstrarea tehnicilor de caching, acest exemplu introduce ceva nou. În primul rând, clasa Factorial3 definește câmpuri statice:

static lung [] tabel = nou lung [21];

static int last = 0;

Câmpurile statice reprezintă un fel de variabile care, totuși, își păstrează valorile în intervalele dintre apelurile către metoda factorial (). Aceasta înseamnă că în câmpurile statice valorile stocate într-un apel de metodă pot fi stocate pentru a fi utilizate la un alt apel la metodă.

În al doilea rând, în acest exemplu, puteți vedea modul în care sunt create cadrele:

static lung [] tabel = nou lung [21];

Prima jumătate a acestei linii (înainte de semnul =) declară un câmp de tabelă statică, care va fi o matrice de valori lungi. A doua jumătate a acestei linii creează o gamă de 21 de valori lungi folosind noul operator.

În cele din urmă, acest exemplu arată cum sunt generate excepțiile:

arunca noua IllegalArgumentException ("Overflow: x este prea mare");

Excepțiile sunt un fel de obiecte Java. Ele, ca și matricele, sunt create folosind cuvântul cheie nou. Dacă programul aruncă un obiect excepțional cu instrucțiunea throw, înseamnă că a apărut o circumstanță sau o eroare neașteptată. Când se produce o excepție, comanda din program este trecută la cea mai apropiată secțiune de captură a operatorului de încercare / prindere. Această secțiune trebuie să conțină coduri pentru tratarea excepțiilor. Dacă excepția nu este interceptată, executarea programului se termină cu un mesaj de eroare.

În Exemplul 1.9, apare o excepție care notifică procedura de apelare că argumentul trecut de către el este prea mare sau prea mic. Argumentul este prea mare dacă este mai mare de 20, deoarece nu putem calcula factoriali mai mari de 20. Argumentul este prea mic dacă este mai mic decât 0, deoarece factoriali sunt definiți numai pentru numere întregi care nu sunt negativi. Modul de interceptare și procesare a excepțiilor este prezentat în următoarele exemple din acest capitol.

clasele sunt utilizate în program. După ce, de exemplu, clasa java.math.BigInteger este importată, nu mai trebuie să scrieți numele său complet; vă puteți referi la ea doar ca BigInteger. De asemenea, puteți importa întregul pachet de clase prin includerea în fișier a următorului rând, de exemplu:

Rețineți că clasele pachetului java.lang sunt importate automat, deoarece aparțin pachetului curent, care în cazul nostru este com.davidflanagan.examples.basics.

Exemplul 1.10 utilizează aceeași tehnică de cache ca în exemplul 1.9. Cu toate acestea, deoarece un număr de factoriali care pot fi calculați nu sunt acum limitați de sus, o matrice de dimensiune fixă ​​nu poate fi folosită pentru cache. În schimb, exemplul folosește java.util.ArrayList, o clasă de utilități care implementează o structură de date similară cu matricea și poate crește la orice dimensiune dorită. Deoarece ArrayList este un obiect, nu un matrice, trebuie să utilizați metode precum dimensiunea (), add () și get () atunci când lucrați cu el. În mod similar, BigInteger este un obiect, nu o valoare primitivă, astfel încât să nu puteți folosi operatorul * pentru a multiplica obiectele BigInteger. În schimb, se folosește metoda multiplicare ().

Exemplul 1.10. Factorial4.java

// Introduceți clasele pe care intenționăm să le folosim în programul nostru.

// Importând o clasă, nu mai trebuie să-i numim un nume complet.

import java.math.BigInteger; // Importăm clasa BigInteger din pachetul java.math import java.util. *; // Import toate clasele (inclusiv ArrayList)

* În această versiune a programului, întregi arbitrar de mare

* dimensiune, deci valorile calculate nu sunt marcate de sus.

* Pentru a cache valorile calculate, obiectul ArrayList este folosit în el

* în loc de matrice de dimensiuni fixe. ArrayList este similar cu o matrice,

* dar poate crește la orice dimensiune. Metoda factorial () este declarată

* ca "sincronizat", astfel încât să poată fi folosit în siguranță în

* Programe multithreaded. Când studiați această clasă, întâlniți-vă

* cu java.math.BigInteger și java.util.ArrayList. Lucrul cu versiunile Java,

* Înainte de Java 1.2, utilizați Vector în loc de ArrayList.

clasa publică Factorial4

tabela protejată statică ArrayList = noul ArrayList (); // Creați cache static

/ ** Metoda factorial () care folosește obiectele BigInteger stocate în ArrayList * /

public static sincronizat BigInteger factorial (int x)

Articole similare