Vous êtes sur la page 1sur 67

Projeto e Anlise de Algoritmos

Slides adaptados dos materiais dos professores: Nivio Ziviani, Antnio Loureiro e Raquel Mini Mnica Machado

O que um algoritmo?
Qualquer procedimento computacional bem definido que toma algum valor ou conjunto de valores como entrada e produz algum valor ou conjunto de valores como sada. Sequncia de passos computacionais que transformam a entrada na sada. Sequncia de aes executveis para a obteno de uma soluo para um determinado tipo de problema. Descrio de um padro de comportamento, expresso em termos de um conjunto finito de aes. Sequncia no ambgua de instrues que executada at que determinada condio se verifique.

Algoritmo correto X incorreto


Um algoritmo correto se, para cada instncia de entrada, ele para com a sada correta. Um algoritmo incorreto pode no parar em algumas instncias de entrada, ou ento pode parar com outra resposta que no a desejada.

Algoritmo eficiente X ineficiente


Algoritmos eficientes so os que executam em tempo polinomial. Algoritmos que necessitam de tempo superpolinomial so chamados de ineficientes.

Anlise de algoritmos
Analisar a complexidade computacional de um algoritmo significa prever os recursos de que o mesmo necessitar: Memria Largura de banda de comunicao Hardware Tempo de execuo Geralmente existe mais de um algoritmo para resolver um problema. A anlise de complexidade computacional fundamental no processo de definio de algoritmos mais eficientes para a sua soluo. Em geral, o tempo de execuo cresce com o tamanho da entrada.

Porque estudar anlise de algoritmos?


O tempo de computao e o espao na memria so recursos limitados. Os computadores podem ser rpidos, mas no so infinitamente rpidos. A memria pode ser de baixo custo, mas finita e no gratuita. Os recursos devem ser usados de forma sensata, e algoritmos eficientes em termos de tempo e espao devem ser projetados. Com o aumento da velocidade dos computadores, tornase cada vez mais importante desenvolver algoritmos mais eficientes, devido ao aumento constante do tamanho dos problemas a serem resolvidos.

Porque estudar anlise de algoritmos?


Suponha que para resolver um determinado problema voc tem disponvel um algoritmo exponencial (2n) e um computador capaz de executar 104 operaes por segundo.

Porque estudar anlise de algoritmos?


Compra de um novo computador capaz de executar 109 operaes por segundo.

Aumento na velocidade computacional tem pouco efeito no tamanho das instncias resolvidas por algoritmos ineficientes

Porque estudar anlise de algoritmos?


Investir em algoritmo: - Voc encontrou um algoritmo quadrtico (n2) para resolver o problema.

Novo algoritmo oferece uma melhoria maior que a compra da nova mquina

Funo de complexidade
Para medir o custo de execuo de um algoritmo comum definir uma funo de custo ou funo de complexidade T. T(n) a medida do tempo necessrio para executar um algoritmo para um problema de tamanho n. Funo de complexidade de tempo: T(n) mede o tempo necessrio para executar um algoritmo para um problema de tamanho n. Na realidade, a complexidade de tempo no representa tempo diretamente, mas o nmero de vezes que determinada operao considerada relevante executada. Obs.: Alguns autores utilizam a notao f(n).

Exemplo: Maior elemento


Considere o algoritmo para encontrar o maior elemento de um vetor de inteiros A[1..n], n 1.

package cap1; public class Max { public static int max ( int v [ ] , int n) { int max = v[0] ; for ( int i = 1; i < n; i++) if (max < v[ i ] ) max = v[ i ] ; return max; } }

Exemplo: Maior elemento


Seja T uma funo de complexidade tal que T(n) seja o nmero de comparaes entre os elementos de A, se A contiver n elementos. Logo T(n) = n 1 para n 1.

Tamanho da entrada de dados


A medida do custo de execuo de um algoritmo depende principalmente do tamanho da entrada de dados. comum considerar o tempo de execuo de um programa como uma funo do tamanho da entrada. Em alguns algoritmos, o custo de execuo esta em funo tambm da forma em que os dados esto organizados e no apenas do tamanho da entrada. No caso da funo Max do programa do exemplo, o custo uniforme sobre todos os problemas de tamanho n. J para um algoritmo de ordenao isso no ocorre: se os dados de entrada j estiverem quase ordenados, ento o algoritmo pode ter que trabalhar menos.

Melhor caso, pior caso e caso mdio


Melhor caso:
Menor tempo de execuo sobre todas as entradas de tamanho n.

Pior caso:
Maior tempo de execuo sobre todas as entradas de tamanho n. Se T uma funo de complexidade baseada na anlise de pior caso, o custo de aplicar o algoritmo nunca maior do que T(n).

Caso mdio (ou caso esperado):


Mdia dos tempos de execuo de todas as entradas de tamanho n.

Melhor caso, pior caso e caso mdio


Na anlise do caso esperado, supe-se uma distribuio de probabilidades sobre o conjunto de entradas de tamanho n e o custo mdio obtido com base nessa distribuio. A anlise do caso mdio geralmente muito mais difcil de obter do que as anlises do melhor e do pior caso.

Exemplo: Registros de um arquivo


Considere o problema de acessar os registros de um arquivo. Cada registro contm uma chave nica que utilizada para recuperar registros do arquivo. O problema: dada uma chave qualquer, localize o registro que contenha esta chave. O algoritmo de pesquisa mais simples o que faz a pesquisa sequencial.

Exemplo: Registros de um arquivo


Seja T uma funo de complexidade tal que T(n) o nmero de registros consultados no arquivo (nmero de vezes que a chave de consulta comparada com a chave de cada registro).
- Melhor caso: T(n) =1 (registro procurado o primeiro consultado) - Pior caso: T(n) = n (registro procurado o ltimo consultado ou no est presente no arquivo)

- Caso mdio: T(n) =(n+1)

Exemplo: Registros de um arquivo


No estudo do caso mdio, vamos considerar que toda pesquisa recupera um registro. Se pi for a probabilidade de que o i-simo registro seja procurado, e considerando que para recuperar o isimo registro so necessrias i comparaes, ento. T(n) = (1 x p1 ) + (2 x p2 ) + (3 x p3 ) + ... + (n x pn )

Exemplo: Registros de um arquivo


Se cada registro tiver a mesma probabilidade de ser acessado que todos os outros, ento pi = 1/n, 1 i n Neste caso: A anlise do caso esperado revela que uma pesquisa com sucesso examina aproximadamente metade dos registros.

Exemplo: Maior e menor elementos (1)


Considere o problema de encontrar o maior e o menor elemento de um vetor de inteiros A[1..n], n 1. Um algoritmo simples pode ser derivado do algoritmo apresentado no programa para achar o maior elemento.

Exemplo: Maior e menor elementos (1)


package cap1; public class MaxMin1 { public static int [ ] maxMin1 ( int v [ ] , int n) { int max = v[0] , min = v[0] ; for ( int i = 1; i < n; i ++) { if (v[ i ] > max) max = v[ i ] ; if (v[ i ] < min) min = v[ i ] ; } int maxMin[ ] = new int [2] ; maxMin[0] = max; maxMin[1] = min; return maxMin; } }

Seja T(n) o nmero de comparaes entre os elementos de A, se A tiver n elementos. Logo T(n) = 2(n 1), para n > 0, para o melhor caso, pior caso e caso mdio.

Exemplo: Maior e menor elementos (2)


MaxMin1 pode ser facilmente melhorado: a comparao A[i] < Min s necessria quando o resultado da comparao A[i] > Max for falso.

Exemplo: Maior e menor elementos (2)


package cap1; public class MaxMin2 { public static int [ ] maxMin2 ( int v [ ] , int n) { int max = v[0] , min = v[0] ; for ( int i = 1; i < n; i ++) { if (v[ i ] > max) max = v[ i ] ; else if (v[ i ] < min) min = v[ i ] ; } int maxMin[ ] = new int [2] ; maxMin[0] = max; maxMin[1] = min; return maxMin; } }

Melhor caso: quando os elementos esto em ordem crescente; T(n) = n 1 Pior caso: quando os elementos esto em ordem decrescente; T(n) = 2(n 1) Caso mdio: No caso mdio, A[i] / v[i] maior do que Max a metade das vezes. T(n) = n 1 + (n 1)/2 = 3n/2 3/2

Exemplo: Maior e menor elementos (3)


Considerando o nmero de comparaes realizadas, existe a possibilidade de obter um algoritmo mais eficiente: 1.Compare os elementos de A aos pares, separando-os em dois subconjuntos (maiores em um e menores em outro), a um custo de n/2 comparaes. 2.O mximo obtido do subconjunto que contm os maiores elementos, a um custo de n/2 -1 comparaes. 3.O mnimo obtido do subconjunto que contm os menores elementos, a um custo de n/2 -1 comparaes.

Exemplo: Maior e menor elementos (3)


Os elementos de A so comparados dois a dois. Os elementos maiores so comparados com Max e os elementos menores so comparados com Min. Quando n mpar, o elemento que est na posio A[n-1] duplicado na posio A[n] para evitar um tratamento de exceo. Para esta implementao: no pior caso, melhor caso e caso mdio

Exemplo: Maior e menor elementos (3)

Exemplo: Maior e menor elementos (3)

Exemplo: Maior e menor elementos (3)


package cap1; public class MaxMin3 { public static int [ ] maxMin3 ( int v [ ] , int n) { int max, min, FimDoAnel; if ( (n % 2) > 0) { v[n] = v[n1]; FimDoAnel = n; } else FimDoAnel = n1; if (v[0] > v [1] ) { max = v [0] ; min = v [1] ; } else { max = v [1] ; min = v [0] ; } int i = 2; while ( i < FimDoAnel) { if (v[ i ] > v[ i +1]) { if (v[ i ] > max) max = v[ i ] ; if (v[ i +1] < min) min = v[ i +1]; } else { if (v[ i ] < min) min = v[ i ] ; if (v[ i +1] > max) max = v[ i +1]; } i = i + 2; } int maxMin[ ] = new int [2] ; maxMin[0] = max; maxMin[1] = min; return maxMin; } }

Comparao 1

Comparao 2 Comparao 3 Comparao 4 Comparao 3 Comparao 4

Comparao entre os algoritmos MaxMin1, MaxMin2 e MaxMin3


A tabela abaixo apresenta uma comparao entre os algoritmos dos programas MaxMin1, MaxMin2 e MaxMin3, considerando o nmero de comparaes como medida de complexidade. Os algoritmos MaxMin2 e MaxMin3 so superiores ao algoritmo MaxMin1 de forma geral. O algoritmo MaxMin3 superior ao algoritmo MaxMin2 com relao ao pior caso e bastante prximo quanto ao caso mdio.

Comparao entre os algoritmos MaxMin1, MaxMin2 e MaxMin3

Comportamento Assinttico de Funes


O parmetro n fornece uma medida da dificuldade para se resolver o problema. Para valores suficientemente pequenos de n, qualquer algoritmo custa pouco para ser executado, mesmo os ineficientes.
A escolha do algoritmo no um problema crtico para problemas de tamanho pequeno (n).

Logo, a anlise de algoritmos realizada para valores grandes de n.


Estuda-se o comportamento assinttico das funes de custo (comportamento de suas funes de custo para valores grandes de n).

Dominao assinttica
A anlise de um algoritmo geralmente conta com apenas algumas operaes elementares. A medida de custo ou medida de complexidade relata o crescimento assinttico da operao considerada.

Dominao assinttica Notao O


Uma funo f(n) domina assintoticamente outra funo g(n) se existem duas constantes positivas c e m tais que, para n m, temos g(n) c f(n). Notao trazida da matemtica por Knuth (1968): g(n) = O(f(n))
L-se: f(n) domina assintoticamente g(n) f(n) um limite assinttico superior para g(n) g(n) da ordem no mximo f(n)

O valor da constante m mostrado o menor valor possvel, mas qualquer valor maior tambm vlido.

Dominao assinttica Notao O


Exemplo:

Sejam g(n) = (n+1)2 e f(n) = n2. As funes g(n) e f(n) dominam assintoticamente uma a outra, desde que: |(n+1) 2| 4|n2| para n 1
|g(n)| c|f(n)| para nm; c=4 e m=1 g(n) = O(f(n))

|n2| |(n+1) 2| para n 0


(onde est a constante no exemplo acima?)

|f(n)| c|g(n)| para nm; c=1 e m=0 f(n) = O(g(n))

Dominao assinttica Notao O


Exemplos:

Seja g(n) = (n+1)2. Logo, g(n) O(n2), quando m=1 e c=4. Isso porque: (n+1) 2 4n2 para n 1. Sejam g(n) = n e f(n) = -n2 Temos que |n| c|-n2|, fazendo c=1e m=0, a definio anterior satisfeita. Desta forma, f(n) domina assintoticamente g(n). g(n) = O(f(n)) Observe que g(n) no domina assintoticamente f(n) porque |-n2| > c|n|, qualquer que seja o valor de c, para todo n>1. A funo g(n) = 3n3 + 2n2 + n O(n3). Basta mostrar que 3n3 + 2n2 + n 6n3, para n 0.

Dominao assinttica Notao


Uma funo g(n) = (f(n)) se existirem constantes positivas c1, c2 e m tais que 0 c1 f(n) g(n) c2 f(n), para todo n m. Dizemos que g(n) = (f(n)) se existirem constantes c1, c2 e m tais que, para todo n m, o valor de g(n) est sobre ou acima de c1 f(n) e sobre ou abaixo de c2 f(n). Neste caso, f(n) um limite assinttico firme.

Dominao assinttica Notao


Seja g(n) = n2/3 2n. Vamos mostrar que g(n) = (n2). Temos de obter constantes c1, c2 e m tais que c1n2 1/3n2 2n c2n2 para todo n m. Dividindo por n2 leva a c1 1/3 2/n c2. O lado direito da desigualdade ser sempre vlido para qualquer valor de n 1 quando escolhemos c2 1/3. Escolhendo c1 1/21, o lado esquerdo da desigualdade ser vlido para qualquer valor de n 7. Logo, escolhendo c1 = 1/21, c2 = 1/3 e m = 7, verifica-se que n2/3 2n = (n2). Outras constantes podem existir, mas o importante que existe alguma escolha para as trs constantes.

Dominao assinttica Notao


Especifica um limite inferior para g(n). Uma funo g(n) (f(n)) se existirem duas constantes c e m tais que g(n) c f(n), para todo n m. Exemplo: Para mostrar que g(n) = 3n3 + 2n2 (n3) basta fazer c=1, e ento 3n3 + 2n2 n3 para n 0.

Classes de Comportamento Assinttico


Se f uma funo de complexidade para um algoritmo F, ento O(f) considerada a complexidade assinttica ou o comportamento assinttico do algoritmo F. A relao de dominao assinttica permite comparar funes de complexidade. Entretanto, se as funes f e g dominam assintoticamente uma a outra, ento os algoritmos associados so equivalentes. Nestes casos, o comportamento assinttico no serve para comparar os algoritmos.

Comparao de Programas
Podemos avaliar programas comparando as funes de complexidade, negligenciando as constantes de proporcionalidade. Um programa com tempo de execuo O(n) melhor que outro com tempo O(n2). Porm, as constantes de proporcionalidade podem alterar esta considerao.
Exemplo: um programa leva 100n unidades de tempo para ser executado e outro leva 2n2. Qual dos dois programas melhor?

Comparao de Programas
Qual dos dois programas melhor? depende do tamanho do problema. Para n < 50, o programa com tempo 2n2 melhor do que o que possui tempo 100n. (Calcule n=40, n=49, n=50 e n=51)
2n2 100n n=40 -> 3200 n=40-> 4000 n=49->4802 n=49->4900 n=50->5000 n=50->5000 n=51->5202 n=51->5100

Para problemas com entrada de dados pequena prefervel usar o programa cujo tempo de execuo O(n2). Entretanto, quando n cresce, o programa com tempo de execuo O(n2) leva muito mais tempo que o programa O(n).

Principais Classes de Problemas


f(n) = O(1).
Algoritmos de complexidade O(1) so ditos de complexidade constante. Uso do algoritmo independe de n. As instrues do algoritmo so executadas um nmero fixo de vezes. O que significa um algoritmo ser O(2) ou O(5)?

Principais Classes de Problemas


f(n) = O(log n).
Um algoritmo de complexidade O(log n) dito de complexidade logartmica. Tpico em algoritmos que transformam um problema em outros menores. Pode-se considerar o tempo de execuo como menor que uma constante grande. Quando n mil, log2n 10, quando n 1milho, log2n 20.
Para n=1 000 , Para n=1 000 000, log2n 10 log2n 20

Exemplo: Algoritmo de pesquisa binria


Lembrando: log28 =3

Principais Classes de Problemas


f(n) = O(n).
Um algoritmo de complexidade O(n) dito de complexidade linear. Em geral, um pequeno trabalho realizado sobre cada elemento de entrada. a melhor situao possvel para um algoritmo que tem de processar/produzir n elementos de entrada/sada. Cada vez que n dobra de tamanho, o tempo de execuo tambm dobra. Exemplo: Algoritmo de pesquisa sequencial

Principais Classes de Problemas


f(n) = O(n log n).
Um algoritmo de complexidade O(n log n) dito de complexidade linear logartmica.
Tpico em algoritmos que quebram um problema em outros menores, resolvem cada um deles independentemente e juntando as solues depois. Caso tpico dos algoritmos baseados no paradigma diviso-econquista.

Quando n 1 milho, nlog2n cerca de 20 milhes. Quando n 2 milhes, nlog2n cerca de 42 milhes Exemplo: Algoritmo de ordenao MergeSort

Principais Classes de Problemas


f(n) = O(n2).
Um algoritmo de complexidade O(n2) dito de complexidade quadrtica. Ocorrem quando os itens de dados so processados aos pares, muitas vezes em um anel dentro de outro. Quando n mil, o nmero de operaes da ordem de 1 milho. Sempre que n dobra, o tempo de execuo multiplicado por 4. teis para resolver problemas de tamanhos relativamente pequenos. Exemplos: Algoritmos de ordenao simples como seleo e insero

Principais Classes de Problemas


f(n) = O(n3).
Um algoritmo de complexidade O(n3) dito de complexidade cbica. teis apenas para resolver pequenos problemas. Quando n 100, o nmero de operaes da ordem de 1 milho. Sempre que n dobra, o tempo de execuo fica multiplicado por 8. Exemplos: Algoritmo para multiplicao de matrizes

Principais Classes de Problemas


f(n) = O(2n).
Um algoritmo de complexidade O(2n) dito de complexidade exponencial. Geralmente no so teis sob o ponto de vista prtico. Ocorrem na soluo de problemas quando se usa fora bruta para resolv-los. Quando n 20, o tempo de execuo cerca de 1 milho. Quando n dobra, o tempo fica elevado ao quadrado. Exemplos: Algoritmo do Caixeiro Viajante

Principais Classes de Problemas


f(n) = O(n!).
Um algoritmo de complexidade O(n!) dito de complexidade exponencial, apesar de O(n!) ter comportamento muito pior do que O(2n). Geralmente ocorrem quando se usa fora bruta para na soluo do problema. Considerando: n = 20 20! = 2432902008176640000, um nmero com 19 dgitos. n = 40 um nmero com 48 dgitos.

Algoritmos Polinomiais
Algoritmo polinomial no tempo de execuo tem funo de complexidade O(p(n)), onde p(n) um polinmio. Algoritmo exponencial no tempo de execuo tem funo de complexidade O(cn), c > 1, so geralmente simples variaes de pesquisa exaustiva. A distino entre estes dois tipos de algoritmos torna-se significativa quando o tamanho do problema a ser resolvido cresce. Por isso, os algoritmos polinomiais so muito mais teis na prtica do que os exponenciais. A distino entre algoritmos polinomiais eficientes e algoritmos exponenciais ineficientes possui excees.
Exemplo: um algoritmo com funo de complexidade f(n) = 2n mais rpido que um algoritmo g(n) = n5 para valores de n menores ou iguais a 20.

Comparao de funes de complexidade

Hierarquias de funes
A seguinte hierarquia de funes pode ser definida do ponto de vista assinttico:

onde e c so constantes arbitrrias com 0 < < 1 < c

Hierarquias de funes

Hierarquias de funes

Tcnicas de Anlise de Algoritmos complexidade


Determinar o tempo de execuo de um programa pode ser um problema matemtico complexo. Determinar a ordem do tempo de execuo, sem preocupao com o valor da constante envolvida, pode ser uma tarefa mais simples. A anlise utiliza tcnicas de matemtica discreta, envolvendo contagem ou enumerao dos elementos de um conjunto: manipulao de somas, produtos, permutaes, fatoriais, coeficientes binomiais, soluo de equaes de recorrncia.

Anlise do Tempo de Execuo


Comando de atribuio, de leitura ou de escrita: O(1). Comando de deciso: tempo dos comandos dentro do comando condicional, mais tempo para avaliar a condio, que O(1). Anel: soma do tempo do corpo do anel mais o tempo de avaliar a condio para terminao (geralmente O(1)), multiplicado pelo nmero de iteraes. Procedimentos no recursivos: cada um deve ser computado separadamente um a um, iniciando com os que no chamam outros procedimentos. Avalia-se ento os que chamam os j avaliados (utilizando os tempos desses). O processo repetido at chegar no programa principal. Procedimentos recursivos: associada uma funo de complexidade f(n) desconhecida, onde n mede o tamanho dos argumentos.

Anlise do Tempo de Execuo Procedimento no Recursivo


Algoritmo para ordenar os n elementos de um conjunto A em ordem ascendente, onde nmero de comparaes a operao relevante.
procedure ordena1 (var A: vetor, integer n); var i, j, min, x: integer; begin for i := 1 to n-1 do begin min := i; for j:= i+1 to n do i f A[ j ] < A[min] then min := j; x := A[min]; A[min] := A[i]; A[i] := x; end; end;

Anlise do Tempo de Execuo Procedimento no Recursivo


Algoritmo para ordenar os n elementos de um conjunto A em ordem ascendente, onde nmero de comparaes a operao relevante.
package cap1; public class Ordenacao { public static void ordena2 ( int v [ ] , int n) { for ( int i = 0; i < n 1; i ++) { int min = i ; for ( int j = i + 1; j < n; j++) if (v[ j ] < v[min] ) min = j ; / * Troca v[min] e v[i] /* int x = v[min] ; v[min] = v[ i ] ; [ i ] = x; } } }

Anlise do Tempo de Execuo Procedimento no Recursivo


Os algoritmos ordena1 e ordena2 realizam a mesma funo. A linha: for i := 1 to n-1 do begin do algoritmo ordena1 executada n 1 vezes, e o tempo total para executar o programa est limitado ao produto de uma constante pelo somatrio de (n i): A linha: for ( int i = 0; i < n 1; i ++) { do algoritmo ordena2 executada n 1 vezes, e o tempo total para executar o programa est limitado ao produto de uma constante pelo somatrio de (n i). Considerarmos o nmero de comparaes como a medida de custo relevante, o programa faz (n2)/2 n/2 comparaes para ordenar n elementos. Considerarmos o nmero de trocas, o programa realiza exatamente n 1 trocas.

Anlise do Tempo de Execuo Procedimento Recursivo


associada uma funo de complexidade T(n) desconhecida, onde n mede o tamanho dos argumentos. Obtemos uma equao de recorrncia para T(n). Resolvemos a equao de recorrncia. Normalmente, as funes recursivas so divididas em duas partes
Chamada recursiva Condio de parada

A condio de parada fundamental para evitar a execuo de loops infinitos

Anlise do Tempo de Execuo Procedimento Recursivo


(1) (2) (3) (4) void pesquisa(n) { if (n <= 1) Condio de parada inspecione elemento e termine else { para cada um dos n elementos inspecione elemento ; pesquisa(n-1) ; Chamada recursiva } }

Seja T(n) uma funo de complexidade que represente o nmero de inspees nos n elementos do conjunto. O custo de execuo das linhas (1) e (2) O(1) e da linha (3) O(n)

Resoluo da equao de recorrncia

Anlise do Tempo de Execuo Procedimento Recursivo


int fat (int n) { if (n<=1) return (1); else return (n * fat(n-1)); }

Se n <= 1 faz uma operao de custo constante. Se n > 1 faz uma operao de custo constante e chama recursivamente a funo.

Procedimento Recursivo: fatorial


int fat (int n) { if (n<=1) return (1); else return (n * fat(n-1)); } int main() { int f; f = fat(5); printf("%d",f); return (0); }

fat(5) = 5 * fat(4) fat(4) = 4 * fat(3) fat(3) = 3 * fat(2) fat(2) = 2 * fat(1) fat(1) = 1

Procedimento Recursivo: fatorial


Qual a equao de recorrncia que descreve a complexidade da funo fatorial? T(n) = T(n-1) + 1 T(1) = 1 Resposta: T(n) = O (n) ou T(n) = T(n-1) + c T(1) = d Resposta: T(n) = O (n) (Raquel Mini e Ziviani)

Perguntas ?

Referncias
Ziviani Laudon Nivio. Projeto de Algoritmos com implementaes em Java e C++, 2007. Ziviani Laudon Nivio. Projeto de Algoritmos com implementaes em Pascal e C, 2003.

Vous aimerez peut-être aussi