Archivio

Archivio per la categoria ‘Algoritmi e strutture dati’

Alberi binari di ricerca

un albero binario di ricerca è una struttura dati puntata che è :

-vuoto

-una terna T=(r,L.R) dove r è un nodo (radice),L e R sono alberi binari di ricerca.  Un L’albero binario di ricerca sopporta 2 strutture dati astratte: code con priorità e dizionari. Esempio di un albero binario di ricerca:

image

La proprietà degli alberi binari di ricerca

Per ogni nodo x,tutti i valori del sotto albero sinistro di x sono inferiori al valore di x  e tutti i valori del sotto albero destro di x sono superiori al valore di x.

Operazioni basilari

Insert:

image

image

Search:

Ricerca di un elemento x. Si confronta x alla radice ;

-se x inferiore si ricerca nel sotto albero sinistro.

-se x è maggiore ,si ricerca nel sotto albero  destro.

Analisi:

image

Delete:

image

Min e Max

il minimo si trova nel nodo piu a sinistra e il massimo si trova nel nodo piu a destra.

image

Successore e Predecessore

image

oppure

Quando right[x]=NIL,successore di x ??

image

Verifica : x è max del sotto albero sinistro di y

Ogni operazione in un albero binario impiega come tempo di esecuzione O(h),h essendo l’altezza dell’albero.

Per risolvere questo problema abbiamo due soluzioni :

-Alberi binari costrutti casualmente.

-Alberi bilanciati

Grazie di aver letto l’articolo. Dubbi ,domande e suggerimenti ?Lo spazio per i commenti è qui sotto.

avatarfirma

Quick Sort

Ciao a tutti,oggi parliamo del quick sort altro algoritmo di ordinamento. E un algoritmo sul posto che  prende in input una sequenza di elementi e produce una sequenza ordinata in output. Di solito si usa l’array come struttura dati della sequenza.

Anche quick sort usa il metodo divide e impera. Per ordinare gli elementi un array A[p..r] con quick sort si procede cosi:

image

Il punto fondamentale nel quick sort è capire come si fa a dividere un array in modo che ogni elemento del primo sotto array sia inferiore o uguale ad ogni elemento del secondo sotto array. Quicksort usa una procedura per farlo:

Partizione.

Analisi di partizione:

Questo è lo pseudo codice:

image

Domanda: ma questo algoritmo cosa fa nel dettaglio?

Per capirlo andiamo a dimostrarne la correttezza con l’invariante di ciclo.

Correttezza di partizione:

l’invariante di ciclo

image

1.Prima del ciclo

Le righe 2 e 3 formano 2 sotto vettori A[p..p-1]  (A[p..i]) e A[p..p-1] (A[i+1..j-1]) vuoti.

Quindi l’invariante è rispettato.

2.Durante il ciclo

Il ciclo score l’array A[p..r-1] con l’indice j e secondo il caso di figura ,mette l’elemento incontrato nel sotto vettore giusto:

-Le righe 5,6,7 si assicurano che ogni volta che abbiamo un elemento  piu piccolo del pivot x (riga 5),questo ultimo viene aggiunto al sotto vettore A[p..i] (la riga 6 aumenta di 1 la dimensione del sotto vettore e la riga 7 mette l’elemento A[j] nel sotto vettore giusto).

-Se invece l’elemento A[j] è maggiore del pivot x, non si fa niente perché la riga 8 li mette automaticamente  nel sotto vettore giusto cioè  A[i+1..j-1].

-La riga 8 serve a scorrere nel vettore A[j..r] con gli elementi che non sono ancora stati inseriti dentro i sotto vettori. L’incremento della riga 8 mette tutti gli elementi che non sono stati cambiati dalla riga 7 (perché magiori del pivot) dentro il sotto vettore A[i+1..j-1].

Quindi anche cui l’invariante di ciclo viene rispettato.

3.Dopo il ciclo

Alla fine j = r il che significa che il sotto vettore A[i+1..j-1] si ferma a r-1 prima del pivot A[r]. La riga 9 scambia il primo elemento di A[i+1..j-1] con A[r],il che significa che cambia questo sotto vettore in A[i+2..r].

Quindi l’invariante è rispettato e l’array è partizionato con il pivot in A[i+1]. da cui si capisce naturalmente la riga 10.

image

Tempo di esecuzione:

righe 1,2,3,9 e 10 impiegano un tempo costante.

il ciclo fa n-1 confronti quindi impiega :

image

Analisi di QuickSort

pseudocodice:

image

La valutazione delle prestazioni del QuickSort dipende dal bilanciamento dei sotto vettori costruito da partizione(). vediamo qualche caso di figura:

image

1. Caso peggiore:

image

2.Caso Migliore

La partizione si divide esattamente a metà ogni volta,allora si usa il teorema fondamentale.:

image

3.Caso 1/10:9/10

image

Grazie di aver letto l’articolo. Dubbi ,domande e suggerimenti ?Lo spazio per i commenti è qui sotto.

avatar firma

Merge Sort

Ciao a tutti ,oggi si parla di un altro algoritmo di ordinamento che prende in input una sequenza di elementi e produce una sequenza ordinata in output. Di solito si usa l’array come struttura dati della sequenza.

Merge Sort si basa sul metodo divide e impera :

1.Divide:  divide la sequenza di n elementi da ordinare in due sotto sequenze di (n/2) elementi ciascuno.

2.Impera: ordina le due sotto sequenze in modo ricorsivo con Merge sort

3.Combina: riunisce le due sequenze ordinate in una sequenza ordinata (soluzione del problema) con Merge.

Il caso elementare arriva quando la sotto sequenza da ordinare ha dimensione uno e quindi non c’è niente da fare perché in questo caso,la sotto sequenza è già ordinata.

Il punto fondamentale del nostro algoritmo rimane quindi la procedura Merge. Vediamo come funziona.

Analisi di Merge:

Immaginate di dover riunire due pacchetti  di carte già ordinate in un solo pacchetto che deve essere anche lui ordinato.

Intuitivamente si procede in questo modo.

1- Si prende la più piccola carta fra le due prime carte dei pacchetti iniziali (che rappresentano il minimo per ogni pacchetto). Si mette la carta presa nel terzo pacchetto.

2.Si ripete il passo 1 finche l’uno dei due pacchetti non si esaurisce.

3.se uno dei pacchetti è esaurito,si prende le carte del pacchetto rimanente e gli si mette nel terzo pacchetto nello stesso ordine.

Merge esegue il processo appena descritto.

Analisi di Merge Sort:

Ecco lo pseudo codice di Merge Sort:

image

Spiegazioni:

A è l’array rappresenta la sequenza da ordinare,p è l’indice del primo elemento e r l’indice dell’ultimo elemento.

Se p>=r ,l’array A[p…r] contiene al massimo un elemento e come detto prima è gia ordinato.

Nel caso contrario (p < r ):

- Si divide A[p..r] a metta in 2 array A[p..q] e A[q+1..r]

-Si impera A[p..q] e A[q+1..r] con Merge Sort

-Si combina  A[p..q] e A[q+1..r] con Merge

Esempio pratico:

Merge Sort è applicato all’array A=<5,2,4,6,1,3,2,6>.

image

Tempo di esecuzione:

Questo algoritmo è ricorsivo ,quindi il suo tempo di esecuzione è una ricorrenza.

Calcoliamo questa ricorrenza.

image

Nel peggior caso ,avremmo un tempo di esecuzione T(n) definito cosi:

image

image

Grazie di aver letto l’articolo. Dubbi ,domande e suggerimenti ?Lo spazio per i commenti è qui sotto.

avatar firma

5 concetti importantissimi in Informatica

Ciao a tutti, oggi vi parlerò di 5 concetti chiave quando si tratta di informatica,programmazione o algoritmi.

1. Caso migliore ,caso peggiore ,caso medio e poi??

Più volte usiamo queste parole per giudicare le prestazioni di un algoritmo.

T(n) è numero di operazioni elementari compiuto da un algoritmo. Per valutare la prestazione di un algoritmo ,ci interessa calcolare questo numero.

-Caso migliore

termine usato per riferirsi al caso di figura in cui è molto facile risolvere un problema con un certo algoritmo e un certo input. In generale in questo caso il numero di operazioni da eseguire dall’algoritmo il minor possibile.

-Caso peggiore

termine usato per riferirsi al caso di figura in cui il numero di operazioni da eseguire dall’algoritmo è il maggior possibile. Si può paragonare questo caso alla realità parlando della sfortuna.

Quindi T(n)=massimo tempo di esecuzione per qualsiasi input di dimensione n.

-Caso medio

termine usato per riferirsi al caso di figura in cui si cerca di predire qual’è il valore medio di T(n) su tutti gli ingressi possibili.

quindi T(n)= valore atteso del tempo di esecuzione su tutti gli ingressi di dimensione n.

Per farlo dobbiamo ipotizzare una distribuzione di probabilità sui dati di input.

Nella valutazione di un algoritmo ,quale caso usare per il calcolo di T(n)?

-Non si usa quasi mai nella valutazione di un algoritmo perché nei casi reali,non succede quasi mai.

-Di solito si usa il caso medio perché copre quasi tutti i casi di figura.

-Conviene però considerare anche il caso peggiore per le seguenti ragioni:

.il caso peggiore ci da un stima massima del tempo di esecuzione

.Capita molto spesso di avere un caso peggiore. Per esempio la ricerca di un dato inesistente in un database.

.A volte il caso medio è molto vicino al caso peggiore.

2.Invariante di ciclo

L’invariante di ciclo è un’affermazione usata per dimostrare la correttezza di un algoritmo. Vediamo come funziona:

Sostanzialmente,vogliamo dimostrare che un’affermazione è vera prima,all’interno e dopo un ciclo.  I passi sono 3:

1.Si dimostra che l’affermazione è vera prima del ciclo

2.si dimostra che l’affermazione rimane vera nel passaggio dell’iterazione i all’iterazione i+1.

3.si dimostra che l’affermazione è vera alla fine del ciclo

Nella maggior parte dei casi il verificarsi del caso 3 combacia con la correttezza dell’algoritmo.

3.Tipo di programmazione

Ce ne sono 3 fondamentali per gli algoritmi:

1.Procedurale

La programmazione procedurale è  una programmazione lineare nel senso che si va  sempre dritto un passo segue l’altro fino al passo finale. E quella più semplice e più naturale da usare.

2.Ricorsiva

La programmazione ricorsiva è una programmazione non lineare perché usa la ricorrenza. La ricorrenza è per un algoritmo ,il fatto di richiamare se stesso una o più volte con argomenti piu piccoli.  L’esempio piu naturale è quello del fattoriale : n!= n*(n-1)!

E molto usato e aiuta a risolvere problemi ripetitivi senza dover riscrivere o modificare più volte lo stesso algoritmo.

3.Dinamica

La programmazione dinamica è un modo di programmare che divide il problema in piccole istanze di se stesso per poi risolverli in modo ricorsivo e ricombinare l soluzioni. La cosa che lo rende dinamico è che le istanze del grande problema non sono indipendenti fra di loro,il  che significa che bisogna sempre tenere dei risultati ottenuti fino ad ora e cosi via.

Campo di applicazione: Problemi di ottimizzazione.

4.Divide and Impera:

Divide and Conquer è un  metodo di risoluzione di problema che consiste nel dividere un problema in piccole istanze di se stesso per poi risolverli in modo ricorsivo e ricombinare l soluzioni.  ci sono 3 passi:

1.Divide

Divide il problema  in sotto problemi cioè piccole istanze di se stesso.

2.Impera

Risolvere i sotto problemi in modo ricorsivo. Se la dimensione del sotto problema è abbastanza piccola,risolvere in modo diretto.

3.Combina

Combinare le soluzioni dei sotto problemi nella soluzione del Grande problema.

5.Analisi di un algoritmo ricorsivo

Valutare la complessità di un algoritmo ricorsivo ci pone davanti a un problema di ricorrenza cioè l’espressione del tempo di esecuzione è una ricorrenza di questo tipo:

image

Come si risolve questa ricorrenza?

esistono 3 modi:

1.Metodo di sostituzione

Questo metodo consiste in 2 passi:

-Congettura del valore di T(n)

-Usare l’induzione matematica per dimostrare la congettura appena fatta.

Esempio pratico:

image

2.Albero di ricorsione

Non è un metodo formale e non dimostra la ricorrenza. Si usa per capire cosa succede in dettaglio e per formulare  una congettura.

Esempio pratico:

image

image

3.Teorema Fondamentale

E un teorema che ci permette di risolvere molto velocemente una ricorrenza della forma:

image

dove  a >=1 e b > 1 sono costante e f(n) è una funzione e n rappresenta interi positivi.  Ci sono 3 casi:

image

Dimostrazione:

La  prima parte della dimostrazione analizza la ricorrenza fondamentale con la supposizione che b sia una potenza esatta di n. Per questa parte ci sono 3 lemmi da dimostrare. Il primo riduce il problema della ricorrenza fondamentale al problema della valutazione di una sommazione. Il secondo lemma valuta questa sommazione. Il terzo lemma mette insieme il primo e il secondo per dimostrare il teorema fondamentale nel caso in cui b è una potenza esatta di n.

Lemma1:

image

Lemma2:

image

Lemma3:

image

Grazie per aver letto l’articolo. Dubbi,domande e suggerimenti?? spazio commenti si trova qui sotto.

avatar firma

Come costruire gli Heaps binari

17/06/2010 1 commento

Salve a tutti oggi si parla di heaps binari. Cosa sono e come vano creati.

Un heap è un array che può essere visualizzato come un albero binario quasi completo .

Quasi completo significa che tutti i livelli ,tranne l’ultimo,sono completi:possono mancare alcune foglie consecutive a partire dall’ultima foglia a destra

Esempio in immagine :

Un array che rappresenta un heap binario è un oggetto con
due attributi:
length[A] `e il numero di elementi (la dimensione) dell’array
heap-size[A] `e il numero di elementi dell’heap memorizzati
nell’array

Ci sono 2 cose fondamentali da sapere sugli heaps :

1. La radice dell’albero è A[1] (si trova in posizione 1)

2. Le operazioni per ricavare il padre Padre[i]  ,il figlio destro destro[i] e il figlio sinistro sinistro[i] di un nodo i sono:

Padre[i]

return  parte intera(i/2)

sinistro[i]

return 2i

destro[i]

return 2i+1

Ecco un esempio di heap binario con la sua visualizzazione in albero binario:

image

Esistono due tipi di heap binari: max-heap e min-heap
In entrambi i tipi di heap binario, i valori dei nodi soddisfano
una proprietà  le cui caratteristiche dipendono dal tipo di heap

Proprietà del max-heap: in un max-heap ogni nodo i diverso
dalla radice `e tale che A[padre[i ]] >= A[i ]

Questa regola ha 2 conseguenze:

1: l’elemento più grande di un max-heap viene memorizzato nella
radice

2: un sottoalbero di un nodo u contiene nodi il cui valore non `e
mai maggiore del valore del nodo u

Il min-heap si comporta in modo duale ,quindi da ora in poi,parlando di heap,mi riferisco a max-heap.

Come costruire un heaps binario ?

Per costruire un heaps abbiamo bisogno di dell’algoritmo HEAPIFY.

Questo algoritmo ha per obbiettivo di mantenere la proprietà del heaps cioè

A[padre[i]] >=A[i]. Quindi come input abbiamo un array in un certo ordine e alla fine in output questo array sarà un heaps binario.

Principio dell’algoritmo:

Prima si cerca il massimo fra il nodo i e i suoi figli ,poi si sostituisce il nodo i con il massimo trovato e si richiama ricorsivamente l’algoritmo per il figlio che ha appena scambiato  valore con i. Praticamente si va verso il basso.

image

largest è la variabile che rappresenta il massimo fra i due figli.

Costo dell’algoritmo.

Il costo di Heapify in un (sotto)albero di dimensione n è pari:
al tempo costante  c  necessario per stabilire il massimo fra gli
elementi A[i ], A[sinistro(i )] e A[destro(i )]
più il tempo per eseguire Heapify in un sottoalbero con radice
uno dei figli di i
La dimensione di ciascun sottoalbero non supera 2n/3 perché siamo in un albero quasi completo.
Il tempo di esecuzione di Heapify può essere espresso dalla
seguente ricorrenza
T(n)<= T(2n/3) + c
Per il teorema master, la soluzione di questa ricorrenza e O(log2 n)

Per la costruzione del heap utilizziamo Heapify su tutti i nodi fra

1 e parte intera(n/2). Perché?

Visto che tutte le foglie possono essere considerate heaps di dimensione 1,basta sistemare con Heapify  tutti i nodi che non sono foglie  in ordine decrescente.

image

Costo di Build-Heap :

Ogni chiamata costa O(log2n) ci sono O(n) chiamate  quindi siamo a O(nlog2n)

Possiamo fare di meglio osservando che il tempo di esecuzione
di Heapify varia al variare dell’altezza del nodo nell’heap.

Un’analisi più rigorosa si basa sulle seguenti informazioni:
-uno heap di n elementi ha un’altezza di log2n
per ogni k = 0, . . . , log2n ci sono al più  n/2k+1 nodi di
altezza k
-una chiamata di Heapify su un nodo di altezza k e O(k)
Il costo T(n) di Build-Heap e limitato da:

image

Dopo i calcoli ci rendiamo conto che il costo di Build-Heap è O(n).

Basta per oggi,Spero che hai imparato qualcosa leggendo questo articolo. Se hai dei dubbi o suggerimenti,lasca un commento qui sotto.

avatar firma

Capire Insertion Sort

Oggi vediamo più in dettaglio l’algoritmo di ordinamento per inserimento.

Come richiesto da l’Algor method ,eseguiro 4 passi.

1.Il Problema

Ordinare dei dati omogenei (dello stesso tipo) o in ordine crescente o decrescente dipendendo dell’applicazione specifica.

2.Struttura dati usata

Di solito si usa un array di interi. Ma questo può variare nelle applicazioni specifiche.

3.Pseudo codice

Praticamente l’algoritmo si comporta come un umane che vuole ordinare una mano di carta. Al ’inizio , tutte le carte sono sul tavolo,con la mono destra prendo una a una le carte e le metto sulla mano sinistra nel posto giusto. Per mettere la carta nel posto giusto ogni volta ,faccio un paragono con le carte della mano sinistra. Ora che sappiamo come fa l’algoritmo ,ecco lo pseudo codice :

INSERTION-SORT(A)

1. for j <– 2  to length[A]
2.      do   key <– A[J]
3.               // inserire A[j] nella sequenza ordinata A[1..j -1]
4.               i <– j – 1
5.               while i>0 and A[i]>key
6.                   do A[i + 1] <– A[i]
7.                         i <– i – 1
8.               A[i + 1] <– key

Notiamo che l’ordinamento usa un solo array per questo si parla di ordinamento in place.

Key rappresenta la nuova carta da inserire ogni volta nella mano sinistra.

A[1..j-1] rappresenta la mano sinistra cioè la parte de l’array già ordinata.

J serve ad indicizzare la variabile da inserire in A[1..j-1]

I permette di scorrere A[1..j-1] cioè da j-1 a 1.

il primo ciclo While è quello che fa prendere ogni volta una variabile key da inserire dentro A[1..j-1].

il secondo ciclo invece è quello che fa trovare il posto giusto a key paragonandolo ogni volta ad un elemento di A[1..j-1].

Ora che abbiamo capito come funziona l’algoritmo attraverso questo pseudo codice calcoliamo la complessità

4.Complessità

Per calcolare la complessità ,dobbiamo calcolare quante volte viene eseguita una istruzione. un istruzione presente in un ciclo viene eseguita un numero di volte pari a quanti indici il ciclo coinvolge con il contatore. Se associamo una costante cj ad ogni istruzione ,otteniamo qualcosa di questo tipo:

image

La somma è quindi  c1*n+c2*(n – 1) + c4*(n – 1) + c5*£ + c6*(£ – 1) + c7*(£ – 1)     + c8*(n – 1)

Ora vediamo di calcolare £. Il ciclo dalla riga 5 alla 7 va dell’indice 1 a j – 1, quindi il costo di ogni riga di questo ciclo diventa cj*(j – 1). Ma ognuna di queste righe si trovano nel grande ciclo che va dalla prima all’ultima riga  (indice coinvolti sono di n – 1); quindi

clip_image002[6]

Questo ci da un risultato dell’ordine di

clip_image002

Conclusione  La somma totale è circa

clip_image002[8]

La complessità nel caso peggiore è quindi  una forma quadratica.

Spero che hai imparato qualcosa leggendo questo articolo. Se hai dei dubbi o suggerimenti,lasca un commento qui sotto.

avatar firma

Come Capire un algoritmo?

Nel campo della programmazione,c’è sempre a che fare con gli algoritmi,oggi vi propongo un metodo semplice per capire ogni nuovo algoritmo che dovrete usare in un vostro programma.Io consiglio a tutti quelli che hanno a che fare con un algoritmo di usare questo metodo prima di passare alla realizzazione del codice.

Ho chiamato questo metodo di 4 passi : la Algor Method. Ora vediamo questi 4 passi:

1.Quale problema risolve il mio algoritmo?

Devo sempre sapere in modo preciso quale problema deve risolvere il mio algoritmo. Questo mi  risparmia dei problemi di comprensione o ambiguità che potrei incontrare durante la programmazione.

2.Quali strutture dati usa il mio algoritmo ?

Devo conoscere la struttura dati usata per una semplice ragione: La sua implementazione. Per poter implementare una struttura dati ,la devo prima conoscere e magari documentarmi se non l’ho mai usata. Questo mi risparmia di dover programmare con la testa fra il libro e lo schermo del Mc Book (non è consigliato fare due cose contemporaneamente :-)   semplice avviso agli super uomini)

3.Qual è il pseudo codice del mio algoritmo ?

il pseudo codice va analizzato e capito riga dopo riga ,visto che vera tradotto poi nel linguaggio di programmazione che uso. Questo lavoro ci permette di capire quale metodo usa l’autore del pseudo codice per risolvere il problema. Questo ci permetterà poi di poter modificarlo a piacimento dentro il codice. uno direbbe semplicemente : “Non puoi modificare qualcosa che non capisci” .

4.qual è la complessità del mio algoritmo?

Dopo i tre fondamentali passi c’è questo ultimo e opzionale passo che ci richiede di analizzare la complessità dell’algoritmo. Questo serve o per cultura (La cultura è come la nutella: più ne hai e più ne spalmi) o per cercare di ottimizzarlo.

Questo è il metodo che uso per capire gli algoritmi che studio e che uso a volte programmando. Se anche tu hai un metodo che usi per capire meglio gli algoritmi che usi ,lascia un commento qui sotto.

firma

Le strutture dati di base in programmazione

Salve a tutti. Oggi parleremmo di strutture dati. Secondo Wikipedia,una struttura dati è un’entità usata per organizzare un insieme di dati all’interno della memoria del computer, ed eventualmente per memorizzarli in una memoria di massa. Esistono delle strutture dati di base come ad esempio un array e ci sono quelle dinamiche che sono l’oggetto di questo articolo.

Per ogni struttura dati esiste un numero di operazioni possibile e tanti modi per la loro implementazione. Ho scelto 6 strutture dati che analizzerò con precisione in un apposito articolo:

  1. Alberi
  • Heaps
  • Alberi binari di ricerca
  • Alberi Rosso e Neri

2.     Le tabelle Hash

3.     I Grafi

Grazie di aver etto questo articolo. Se hai delle domande o suggerimenti,lascia un commento qui sotto.

Gli algoritmi di base in programmazione

Oggi sono molto emozionato perché questo è il mio primo articolo sulla programmazione. Parlerò degli algoritmi da conoscere. Per ogni algoritmo faro un articolo che parla della sua implementazione e delle sue prestazioni. Prima di cominciare ti faccio una domanda: Cos’è un algoritmo? Wikipedia risponde cosi: « sequenza logica di istruzioni elementari (univocamente interpretabili) che, eseguite in un ordine stabilito, permettono la soluzione di un problema in un numero finito di passi » Un algoritmo a essenzialmente 4 caratteristiche: -Non ambiguità: Le istruzioni devono essere ben definite. -Correttezza: Ogni informazione di ingresso deve fornire l’informazione giusta in uscita. -Terminazione: Per ogni informazione di ingresso dobbiamo avere una sequenza finita di passi . -Prestazioni: Il modo in cui un algoritmo gestisce le risorse di cui ha bisogno.Per aumentare le prestazioni di un algoritmo,bisogna minimizzare il numero di passi e le risorse che usa. Ora che sai un po’

Technorati Tag:
Technorati Tag:

di più sugli algoritmi,ti parlerò di 12 algoritmi che potranno servirti in programmazione.

  1. Ordinamento

Per risolvere problemi di ordinamento abbiamo 5 algoritmi di base:

2.      Ricerca Per risolvere problemi di ricerca abbiamo 2 algoritmi di base:

  • ricerca sequenziale
  • ricerca per dicotomia

3.     Problemi vari

  • Calcolo del massimo comune divisore (Mcd) con il metodo di Euclide
  • Recursive squaring  per il calcolo delle potenze intere
  • Calcolo dei numeri di fibonacci
  • Moltiplicazione di matrice
  • Sottosequenza comune più lunga

Grazie per aver letto il mio articolo. Ci vediamo al prossimo che scriverò. Se hai delle domande ,non esitare a commentare qui sotto.

Iscriviti

Get every new post delivered to your Inbox.