A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Introdução à Programação Um enfoque orientado a construção de modelos em programas baseados em objetos Gustavo Motta Departamento de Informática - UFPB.

Apresentações semelhantes


Apresentação em tema: "Introdução à Programação Um enfoque orientado a construção de modelos em programas baseados em objetos Gustavo Motta Departamento de Informática - UFPB."— Transcrição da apresentação:

1 Introdução à Programação Um enfoque orientado a construção de modelos em programas baseados em objetos Gustavo Motta Departamento de Informática - UFPB

2 (C) 2008 Gustavo Motta2 6. Comandos iterativos e recursão Comandos iterativos ou de repetição Comandos iterativos ou de repetição Definição Definição Um comando iterativo (também chamado de laço) tem um subcomando (o corpo do laço) que é executado repetidamente e uma cláusula que determina quando a repetição cessará Um comando iterativo (também chamado de laço) tem um subcomando (o corpo do laço) que é executado repetidamente e uma cláusula que determina quando a repetição cessará Essencial para uma linguagem ser universal Essencial para uma linguagem ser universal Necessários em muitos modelos e aplicações Necessários em muitos modelos e aplicações Calcular a média das notas de todos os alunos de uma turma Calcular a média das notas de todos os alunos de uma turma Comparar a seqüência de caracteres em um string que representa parte de um DNA com outra, caractere por caractere, do primeiro até o último Comparar a seqüência de caracteres em um string que representa parte de um DNA com outra, caractere por caractere, do primeiro até o último Repetir a leitura da senha de um usuário enquanto ela não estiver correta Repetir a leitura da senha de um usuário enquanto ela não estiver correta

3 (C) 2008 Gustavo Motta3 6. Comandos iterativos e recursão Comandos iterativos ou de repetição Comandos iterativos ou de repetição Modalidades Modalidades Comandos de iteração indefinida Comandos de iteração indefinida Aqueles nos quais o número de iterações não é determinado previamente Aqueles nos quais o número de iterações não é determinado previamente Depende de uma condição de repetição Depende de uma condição de repetição Enquanto não alcançar a última linha do arquivo, continue lendo a próxima linha para imprimi-la Enquanto não alcançar a última linha do arquivo, continue lendo a próxima linha para imprimi-la Em Java, são os comandos while e do-while Em Java, são os comandos while e do-while Comandos de iteração definida Comandos de iteração definida Aqueles nos quais o número de iterações é sabido antecipadamente Aqueles nos quais o número de iterações é sabido antecipadamente Caracterizado pelo uso de uma variável de controle, denominada de contador do laço Caracterizado pelo uso de uma variável de controle, denominada de contador do laço Some os valores de uma seqüência de números, desde a primeira posição, até a centésima Some os valores de uma seqüência de números, desde a primeira posição, até a centésima Em Java, é o comando for Em Java, é o comando for

4 (C) 2008 Gustavo Motta4 O comando while O comando while while (expressão-lógica) subcomando; while (expressão-lógica) subcomando; while (expressão-lógica) { subcomando_1; subcomando_2;... subcomando_n; } while (expressão-lógica) { subcomando_1; subcomando_2;... subcomando_n; } A avaliação da expressão-lógica determina a condição de repetição. Caso true, o subcomando (ou o bloco de subcomandos) é executado e a condição é reavaliada A avaliação da expressão-lógica determina a condição de repetição. Caso true, o subcomando (ou o bloco de subcomandos) é executado e a condição é reavaliada Enquanto a condição for true, o subcomando é executado Enquanto a condição for true, o subcomando é executado Quando a condição for false, o comando while é encerrado e o próximo comando é executado Quando a condição for false, o comando while é encerrado e o próximo comando é executado 6. Comandos iterativos e recursão

5 (C) 2008 Gustavo Motta5 O comando while O comando while Exemplo: calcular o somatório dos primeiros N números inteiros positivos Exemplo: calcular o somatório dos primeiros N números inteiros positivos int somatório(int n) { int soma = 0, proximoInt = 1; while (proximoInt <= n) { soma = soma + proximoInt; proximoInt = proximoInt + 1; } return soma; }... System.out.println(Somátório de 5: +somatório(5)); 6. Comandos iterativos e recursão 1 2 Memória 3 n 5 soma 0 proximoInt 1 soma 1 proximoInt 2 soma 3 proximoInt 3 soma 6 proximoInt 4 soma 10 proximoInt 5 soma 15 proximoInt 6 Somatório de 5: 15 1 2 Memória 3

6 (C) 2008 Gustavo Motta6 O comando while O comando while Recomendações de verificação Recomendações de verificação Verificar se a condição de repetição inicial do while permite a entrada no laço de forma correta Verificar se a condição de repetição inicial do while permite a entrada no laço de forma correta Caso a condição inicial seja false, o subcomando ou bloco de subcomandos do while não será executado nem mesmo uma vez Caso a condição inicial seja false, o subcomando ou bloco de subcomandos do while não será executado nem mesmo uma vez Caso o valor de n seja zero ou negativo, a condição inicial é false, bloco de subcomandos do while do exemplo anterior não é executado nenhuma vez e o resultado do somatório é 0 Caso o valor de n seja zero ou negativo, a condição inicial é false, bloco de subcomandos do while do exemplo anterior não é executado nenhuma vez e o resultado do somatório é 0 Nesta versão abaixo do exemplo anterior, o bloco de subcomandos do laço nunca é executado porque a condição sempre é false Nesta versão abaixo do exemplo anterior, o bloco de subcomandos do laço nunca é executado porque a condição sempre é false int somatório(int n) { int soma = 0, proximoInt = n + 1; while (proximoInt <= n) { soma = soma + proximoInt; proximoInt = proximoInt + 1; } return soma; } 6. Comandos iterativos e recursão Pode-se usar o próprio comando while para obrigar o usuário a entrar somente com números inteiros positivos Scanner entrada = new Scanner (System.in); int intPositive = entrada.nextInt(); while (intPositive <= 0) { System.out.println("===O numero nao pode ser negativo ou zero==="); intPositive = entrada.nextInt(); } int soma = demowhile.somatório(intPositive); System.out.println("Somatorio de "+intPositive+": "+soma);

7 (C) 2008 Gustavo Motta7 O comando while O comando while Recomendações de verificação Recomendações de verificação Verificar se a condição de repetição do while permite o encerramento no laço de acordo com a modificação, no bloco de subcomandos do laço, das variáveis usadas na condição Verificar se a condição de repetição do while permite o encerramento no laço de acordo com a modificação, no bloco de subcomandos do laço, das variáveis usadas na condição No exemplo anterior, supondo que proximoInt = 1 e que n é positivo, o subcomando proximoInt = proximoInt + 1; no do laço assegura que a condição proximoInt <= n será false numa dada iteração do while, ou seja, o número de repetições sempre será finito (igual a n ) No exemplo anterior, supondo que proximoInt = 1 e que n é positivo, o subcomando proximoInt = proximoInt + 1; no do laço assegura que a condição proximoInt <= n será false numa dada iteração do while, ou seja, o número de repetições sempre será finito (igual a n ) Caso a condição seja sempre true, isto é, não possa variar com a execução sucessiva do bloco de subcomandos do while, então o programa continuará executando para sempre, ou seja, o número de repetições será infinito Caso a condição seja sempre true, isto é, não possa variar com a execução sucessiva do bloco de subcomandos do while, então o programa continuará executando para sempre, ou seja, o número de repetições será infinito 6. Comandos iterativos e recursão Por exemplo, o comando while abaixo nunca termina porque a sua condição do sempre será verdadeira (sendo n inicialmente >= 1), ou seja, não varia com a execução dos subcomandos do laço int somatório(int n) { int soma = 0, proximoInt = 1; while (proximoInt <= n) { soma = soma + proximoInt; proximoInt = proximoInt + 0; } return soma; } Embora não termine de forma normal, é possível interromper anormalmente um programa (em loop) com comandos do sistema operacional ou simplesmente desligando o computador, porém os resultados obtidos podem ser indesejáveis

8 (C) 2008 Gustavo Motta8 O comando while O comando while Recomendações de verificação Recomendações de verificação Quando se tratar de números no comando while, deve-se observar a possibilidade da ocorrência de overflow Quando se tratar de números no comando while, deve-se observar a possibilidade da ocorrência de overflow Em números inteiros, o overflow ocorre quando o resultado da avaliação de uma expressão aritmética é um número maior (ou menor) que o maior (menor) número que pode ser representado num dado tipo inteiro Em números inteiros, o overflow ocorre quando o resultado da avaliação de uma expressão aritmética é um número maior (ou menor) que o maior (menor) número que pode ser representado num dado tipo inteiro Por exemplo, uma variável do tipo byte pode armazenar qualquer valor no intervalo -128 até + 127 Por exemplo, uma variável do tipo byte pode armazenar qualquer valor no intervalo -128 até + 127 byte contador = 127; contador = (byte) (contador + 1); System.out.println(Contador: +contador); No exemplo acima, -128 é o valor impresso No exemplo acima, -128 é o valor impresso 6. Comandos iterativos e recursão Isto porque se o resultado não pode ser armazenado, o valor efetivamente armazenado corresponde ao menor valor armazenável (-128 no caso do tipo byte) adicionado pelo valor que excede o maior valor armazenável menos 1 valorArmazenado = menorInteiro + (Resultado – maiorInteiro – 1) Por exemplo, caso se tente armazenar o valor 200 numa variável do tipo short, o valor efetivamente armazenado será valorArmazenado = – 128 + (200 – 127 – 1) = – 56 É importante frisar que o nem o compilador, nem a maquina virtual Java, acusa este tipo de erro. Cabe ao programador tomar cuidado, examinando cuidadosamente os limites máximos e mínimos potencialmente assumidos em variáveis inteiras e sua adequação do tipo escolhido: byte, short, int ou long

9 (C) 2008 Gustavo Motta9 O comando while O comando while Recomendações de verificação Recomendações de verificação Quando se tratar de números no comando while, deve-se observar a possibilidade da ocorrência de overflow Quando se tratar de números no comando while, deve-se observar a possibilidade da ocorrência de overflow Em números de ponto flutuante, o overflow também pode ocorrer, mas nestes casos, a linguagem Java estabelece valores constantes especiais para designar o infinito positivo e o infinito negativo Em números de ponto flutuante, o overflow também pode ocorrer, mas nestes casos, a linguagem Java estabelece valores constantes especiais para designar o infinito positivo e o infinito negativo Por exemplo, ao final da execução do código abaixo Por exemplo, ao final da execução do código abaixo float valor = Float.MAX_VALUE; valor = valor * 2; System.out.println(Valor: + valor); Float No exemplo acima, Infinity é o valor impresso e corresponde ao valor da constante Float.POSITIVE_INFINITY definida na classe Float da biblioteca de classes de Java No exemplo acima, Infinity é o valor impresso e corresponde ao valor da constante Float.POSITIVE_INFINITY definida na classe Float da biblioteca de classes de Java Float 6. Comandos iterativos e recursão

10 (C) 2008 Gustavo Motta10 O comando while O comando while Recomendações de verificação Recomendações de verificação Quando se tratar de números de ponto flutuante no comando while, deve-se observar a possibilidade da ocorrência de underflow Quando se tratar de números de ponto flutuante no comando while, deve-se observar a possibilidade da ocorrência de underflow O underflow pode ocorrer quando o tipo ponto flutuante não for capaz de representar um número muito próximo de zero O underflow pode ocorrer quando o tipo ponto flutuante não for capaz de representar um número muito próximo de zero Por exemplo, ao final da execução do código abaixo Por exemplo, ao final da execução do código abaixo float quociente = 1; while (quociente > 0) { System.out.println(quociente); quociente = quociente / 2; } float quociente = 1; while (quociente > 0) { System.out.println(quociente); quociente = quociente / 2; } o valor da variável quociente é zero, embora devesse ser um número muito pequeno, próximo de zero, mas não zero 6. Comandos iterativos e recursão O compilador arredonda para zero valores muito próximos de zero que não podem ser representados num dado número de ponto flutuante Cabe ao programador tomar todas as precauções necessárias!

11 (C) 2008 Gustavo Motta11 O comando while O comando while Recomendações de verificação Recomendações de verificação Seja cuidadoso ao usar desigualdades em condições de controle de repetições no comando while Seja cuidadoso ao usar desigualdades em condições de controle de repetições no comando while Por exemplo, a execução do código abaixo Por exemplo, a execução do código abaixo float saldo = 10; while (saldo != 0) { System.out.println(saldo); saldo = saldo – 0.1f; } float saldo = 10; while (saldo != 0) { System.out.println(saldo); saldo = saldo – 0.1f; } nunca termina, pois devido a imprecisão na representação de números decimais (e. g., o valor 0.1) em notação de ponto flutuante em base binário, o valor do saldo passa de um número positivo muito próximo de zero para um número negativo também muito próximo a zero, mas sem ser zero, como esperado 6. Comandos iterativos e recursão Em casos como este, deve-se evitar o uso de desiguladades. O código anterior pode ser reescrito da forma mais segura abaixo float saldo = 10; while (saldo >= 0) { System.out.println(saldo); saldo = saldo – 0.1f; }

12 (C) 2008 Gustavo Motta12 O comando while O comando while Comandos de iteração em Java podem ser encerrados abruptamente, independente da condição de repetição, com o uso do comando break Comandos de iteração em Java podem ser encerrados abruptamente, independente da condição de repetição, com o uso do comando break Sempre que um break é executado dentro de um laço, ele força o seu encerramento imediato, seguindo o programa o fluxo normal de execução do próximo comando após o laço Sempre que um break é executado dentro de um laço, ele força o seu encerramento imediato, seguindo o programa o fluxo normal de execução do próximo comando após o laço Por exemplo, o laço abaixo Por exemplo, o laço abaixo while (true) { String opcao = entrada.nextLine(); if (opcao.equals(s)) break; System.out.println(opcao); } while (true) { String opcao = entrada.nextLine(); if (opcao.equals(s)) break; System.out.println(opcao); } só termina quando o valor opcao for igual a s e o valor de opcao só é impresso se ela for diferente de s 6. Comandos iterativos e recursão

13 (C) 2008 Gustavo Motta13 O comando while O comando while Comandos de iteração em Java podem ser parcialmente interrompidos com o comando continue Comandos de iteração em Java podem ser parcialmente interrompidos com o comando continue Sempre que um continue é executado dentro de um laço, ele interrompe a execução dos subcomandos do laço nesta iteração, a partir do próximo subcomando, voltando para a avaliação da condição de terminação do laço Sempre que um continue é executado dentro de um laço, ele interrompe a execução dos subcomandos do laço nesta iteração, a partir do próximo subcomando, voltando para a avaliação da condição de terminação do laço Por exemplo, no laço abaixo Por exemplo, no laço abaixo String opcao = a; while (! opcao.equals(s)) { opcao = entrada.nextLine(); if ( opcao.equals(s)) continue; System.out.println(Entre Opção diferente de s); } o último subcomando só é executado quando a opção é diferente de s. Caso contrário, o continue força o desvio do fluxo de execução para a avaliação da condição do laço 6. Comandos iterativos e recursão

14 (C) 2008 Gustavo Motta14 6. Comandos iterativos e recursão O comando do-while O comando do-while do { subcomando_1; subcomando_2;... subcomando_n; } while (expressão-lógica); A avaliação da expressão-lógica determina a condição de repetição A avaliação da expressão-lógica determina a condição de repetição Enquanto a condição for true, o bloco de subcomandos é executado Enquanto a condição for true, o bloco de subcomandos é executado Quando a condição for false, o comando do-while é encerrado e o próximo comando é executado Quando a condição for false, o comando do-while é encerrado e o próximo comando é executado A diferença em relação ao comando while é que o bloco de subcomandos é, necessariamente, executado pelo menos uma vez A diferença em relação ao comando while é que o bloco de subcomandos é, necessariamente, executado pelo menos uma vez

15 (C) 2008 Gustavo Motta15 O comando do-while O comando do-while Exemplo: ler a opção do menu de uma aplicação Exemplo: ler a opção do menu de uma aplicação int menuCartãoCrédito() { int opcao = 0; Scanner entrada = new Scanner(System.in); do { System.out.print(1 - compra | 2 - paga | 3 - ver saldo | ); System.out.println(4 - ver bonus | 5 - encerra: "); System.out.print("Sistema de Cartao de Credito. ); System.out.print("Escolha a opcao: "); opcao = entrada.nextInt(); Scanner entrada = new Scanner(System.in); do { System.out.print(1 - compra | 2 - paga | 3 - ver saldo | ); System.out.println(4 - ver bonus | 5 - encerra: "); System.out.print("Sistema de Cartao de Credito. ); System.out.print("Escolha a opcao: "); opcao = entrada.nextInt(); } while (!(opcao > = 1 && opcao = 1 && opcao <= 5)); return opcao; } 6. Comandos iterativos e recursão

16 (C) 2008 Gustavo Motta16 Contadores Contadores Contadores são variáveis que recebem um valor inicial e que são modificadas a cada iteração de comando de repetição de Java Contadores são variáveis que recebem um valor inicial e que são modificadas a cada iteração de comando de repetição de Java Contadores são modificados mediante a atribuição do resultado da avaliação de uma expressão aritmética envolvendo o próprio contador Contadores são modificados mediante a atribuição do resultado da avaliação de uma expressão aritmética envolvendo o próprio contador soma = soma + 1; soma = soma + 1; fatorial = fatorial * n; fatorial = fatorial * n; saldo = saldo – 100; saldo = saldo – 100; quociente = quociente / 2; quociente = quociente / 2; Java permite a utilização de operadores especiais para modificação de variáveis que são contadores Java permite a utilização de operadores especiais para modificação de variáveis que são contadores 6. Comandos iterativos e recursão

17 (C) 2008 Gustavo Motta17 Contadores Contadores Operador ++ : quando aplicado a uma variável numérica, incrementa o valor da variável em um Operador ++ : quando aplicado a uma variável numérica, incrementa o valor da variável em umsoma++; é o mesmo que é o mesmo que soma = soma + 1; Além de modificar o valor, o operador ++ retorna um valor Além de modificar o valor, o operador ++ retorna um valor Caso o operador seja aplicado à direita do operando, o valor retornado é igual ao valor da variável antes da aplicação, por exemplo Caso o operador seja aplicado à direita do operando, o valor retornado é igual ao valor da variável antes da aplicação, por exemplo int resultado = 0, contador = 1; resultado = contador++; int resultado = 0, contador = 1; resultado = contador++; o conteúdo da variável resultado após a atribuição é 1 enquanto o conteúdo de contador é 2 o conteúdo da variável resultado após a atribuição é 1 enquanto o conteúdo de contador é 2 Caso o operador fosse aplicado à esquerda Caso o operador fosse aplicado à esquerda resultado = ++contador; resultado = ++contador; o conteúdo de ambas as variáveis seria 2 o conteúdo de ambas as variáveis seria 2 6. Comandos iterativos e recursão

18 (C) 2008 Gustavo Motta18 Contadores Contadores Operador -- : quando aplicado a uma variável numérica, decrementa o valor da variável em um Operador -- : quando aplicado a uma variável numérica, decrementa o valor da variável em umtotal--; é o mesmo que é o mesmo que total = total - 1; Além de modificar o valor, o operador retorna um valor Além de modificar o valor, o operador retorna um valor Caso o operador seja aplicado à direita do operando, o valor retornado é igual ao valor da variável antes da aplicação, por exemplo Caso o operador seja aplicado à direita do operando, o valor retornado é igual ao valor da variável antes da aplicação, por exemplo int resultado = 0, total = 100; resultado = total--; int resultado = 0, total = 100; resultado = total--; o conteúdo da variável resultado após a atribuição é 100 enquanto o conteúdo de total é 99 o conteúdo da variável resultado após a atribuição é 100 enquanto o conteúdo de total é 99 Caso o operador fosse aplicado à esquerda Caso o operador fosse aplicado à esquerda resultado = --total; resultado = --total; o conteúdo de ambas as variáveis seria 99 o conteúdo de ambas as variáveis seria 99 6. Comandos iterativos e recursão

19 (C) 2008 Gustavo Motta19 Contadores Contadores Operador += : quando aplicado a uma variável numérica, adiciona, ao valor da variável atribuída, o valor à direita do operando Operador += : quando aplicado a uma variável numérica, adiciona, ao valor da variável atribuída, o valor à direita do operando saldo += 100; é o mesmo que é o mesmo que saldo = saldo + 100; Operador -= : quando aplicado a uma variável numérica, subtrai, do valor da variável atribuída, o valor à direita do operando Operador -= : quando aplicado a uma variável numérica, subtrai, do valor da variável atribuída, o valor à direita do operando saldo -= 50; é o mesmo que é o mesmo que saldo = saldo - 50; 6. Comandos iterativos e recursão

20 (C) 2008 Gustavo Motta20 Contadores Contadores Operador *= : quando aplicado a uma variável numérica, multiplica, o valor da variável atribuída, pelo valor à direita do operando Operador *= : quando aplicado a uma variável numérica, multiplica, o valor da variável atribuída, pelo valor à direita do operando fatorial *= n; é o mesmo que é o mesmo que fatorial = fatorial * n; fatorial = fatorial * n; Operador /= : quando aplicado a uma variável numérica, divide, o valor da variável atribuída, pelo valor à direita do operando Operador /= : quando aplicado a uma variável numérica, divide, o valor da variável atribuída, pelo valor à direita do operando quociente /= 100; quociente /= 100; o mesmo que o mesmo que quociente = quociente / 100; quociente = quociente / 100; 6. Comandos iterativos e recursão

21 (C) 2008 Gustavo Motta21 O comando for O comando for for (inicialização; expressão-lógica; atualização) subcomando; for (inicialização; expressão-lógica; atualização) subcomando; for (inicialização; expressão-lógica; atualização) { subcomando_1; subcomando_2;... subcomando_n; } for (inicialização; expressão-lógica; atualização) { subcomando_1; subcomando_2;... subcomando_n; } inicialização atribui um valor inicial para o contador do for inicialização atribui um valor inicial para o contador do for expressão-lógica estabelece a condição de repetição do laço expressão-lógica estabelece a condição de repetição do laço atualização modifica o valor do contador do for atualização modifica o valor do contador do for 6. Comandos iterativos e recursão

22 (C) 2008 Gustavo Motta22 6. Comandos iterativos e recursão O comando for O comando for Exemplo: calcular o fatorial de N Exemplo: calcular o fatorial de N long (int n) { long fat = 1; for (int i = 1; i <= n; i++) { fat = fat * i; } return fat; }... System.out.println(Fatorial de 5: + fatorial(5)); long fatorial(int n) { long fat = 1; for (int i = 1; i <= n; i++) { fat = fat * i; } return fat; }... System.out.println(Fatorial de 5: + fatorial(5)); 1 2 Memória 3 n 5 fat 1 Fatorial de 5: 120 i 1 i 2 fat 2 i 3 6 i 4 i 5 24 fat 120

23 (C) 2008 Gustavo Motta23 O comando for O comando for Outras formas de uso Outras formas de uso int contador; for (contador = 0; contador = 0; contador -= 10) { System.out.println(contador); } for (double controle = 0;controle = 0; contador -= 10) { System.out.println(contador); } for (double controle = 0;controle < 0; controle += 3.5) { System.out.println(controle); } 6. Comandos iterativos e recursão

24 (C) 2008 Gustavo Motta24 O comando for O comando for Outras formas de uso Outras formas de uso double início = 100; double início = 100; double fim = 200; double fim = 200; double incremento = 2.5; double incremento = 2.5; for(;;) { //executa para sempre for(;;) { //executa para sempre System.out.println(início); System.out.println(início); if (início >= fim) break; if (início >= fim) break; início += incremento; } início += incremento; } for (contador = 0;contador < 1000; contador+=2) { System.out.println(contador); System.out.println(contador); contador = 0; contador = 0;} 6. Comandos iterativos e recursão

25 (C) 2008 Gustavo Motta25 6. Comandos iterativos e recursão Recursão Recursão Recursão (ou recursividade) é uma técnica de programação na qual uma computação é definida em termos dela mesma Recursão (ou recursividade) é uma técnica de programação na qual uma computação é definida em termos dela mesma long n) { if (n <= 1) { return 1; } else { return n * ; } }... System.out.println(Fatorial de 5: + fatorial(5)); long fatorial(int n) { if (n <= 1) { return 1; } else { return n * fatorial(n - 1); } }... System.out.println(Fatorial de 5: + fatorial(5)); 1 2 Memória 3 4 5 n = 5) { n 5 n = 4) { n 4 5 * fatorial(4)5 * 4 * fatorial(3) n = 3) { n 3 5 * 4 * 3 * fatorial(2) n = 2) { n 2 5 * 4 * 3 * 2 * fatorial(1) n = 1) { n 1 5 * 4 * 3 * 2 * 1 5 * 4 * 3 * 2 n = 2) { 5 * 4 * 6 n = 3) { 5 * 24 n = 4) { 120 n = 4) { Fatorial de 5: 120 n) { Drawing Hands (1948), litogravuraDrawing Hands (1948), litogravura - M C EscherM C Escher

26 (C) 2008 Gustavo Motta26 6. Comandos iterativos e recursão Recursão Recursão A natureza da recursividade A natureza da recursividade Existem um ou mais casos simples de um problema, chamados de casos de parada, que têm solução trivial Existem um ou mais casos simples de um problema, chamados de casos de parada, que têm solução trivial Os demais casos podem ser solucionados pela substituição para uma versão reduzida do problema, mais próximo do caso de parada Os demais casos podem ser solucionados pela substituição para uma versão reduzida do problema, mais próximo do caso de parada Num dado momento, o problema se reduz a um caso de parada, que permite a resolução do demais casos Num dado momento, o problema se reduz a um caso de parada, que permite a resolução do demais casos fatorial 1 = 1 fatorial n = n * fatorial n - 1 n * n – 1 * n – 2 *... * 1 A recursividade pode ser usada como uma alternativa para iteração Em geral, é uma solução menos eficiente em termos de tempo e espaço Em muitos casos, oferece soluções naturais e simples para problemas que são difíceis de resolver com comandos iterativos

27 (C) 2008 Gustavo Motta27 6. Comandos iterativos e recursão Recursão Recursão Exemplo: torres de Hanói Exemplo: torres de Hanóitorres de Hanóitorres de Hanói Objetivo: mover os 5 discos do pino 1 para o pino 3, obedecendo as seguintes regras Objetivo: mover os 5 discos do pino 1 para o pino 3, obedecendo as seguintes regras Apenas um disco pode ser movido por vez, sempre o disco no topo de algum pino Apenas um disco pode ser movido por vez, sempre o disco no topo de algum pino Um disco de diâmetro maior jamais pode ser colocado sobre um disco com diâmetro menor Um disco de diâmetro maior jamais pode ser colocado sobre um disco com diâmetro menor 1 2 3 1 2 3 4 5

28 (C) 2008 Gustavo Motta28 6. Comandos iterativos e recursão Recursão Recursão Exemplo: torres de Hanói Exemplo: torres de Hanói Solução Solução Caso de parada Caso de parada Mover um único disco de um pino para outro, por exemplo, mover o disco 1 para o pino 3 Mover um único disco de um pino para outro, por exemplo, mover o disco 1 para o pino 3 Versão reduzida do problema Versão reduzida do problema 1. Mover 4 discos do pino 1 para o pino 2 1. Mover 4 discos do pino 1 para o pino 2 2. Mover o disco 5 para o pino 3 2. Mover o disco 5 para o pino 3 3. Mover 4 discos do pino 2 para o pino 3 3. Mover 4 discos do pino 2 para o pino 3 1 2 3 1 2 3 4 5

29 (C) 2008 Gustavo Motta29 6. Comandos iterativos e recursão Recursão Recursão Exemplo: torres de Hanói Exemplo: torres de Hanói Solução Solução Refinamento do passo 1 Refinamento do passo 1 1. Mover 4 discos do pino 1 para o pino 2 1. Mover 4 discos do pino 1 para o pino 2 1.1 Mover 3 discos do pino 1 para o pino 3 1.1 Mover 3 discos do pino 1 para o pino 3 1.2 Mover o disco 4 do pino 1 para o pino 2 1.3 Mover 3 discos do pino 3 para o pino 2 1.3 Mover 3 discos do pino 3 para o pino 2 1 2 3 1 2 3 4 5

30 (C) 2008 Gustavo Motta30 6. Comandos iterativos e recursão Recursão Recursão Exemplo: torres de Hanói Exemplo: torres de Hanói Solução Solução Refinamento do passo 1.1 Refinamento do passo 1.1 1.1 Mover 3 discos do pino 1 para o pino 3 1.1 Mover 3 discos do pino 1 para o pino 3 1.1.1 Mover 2 discos do pino 1 para o pino 2 1.1.1 Mover 2 discos do pino 1 para o pino 2 1.1.2 Mover o disco 3 do pino 1 para o pino 3 1.1.3 Mover 2 discos do pino 2 para o pino 3 1.1.3 Mover 2 discos do pino 2 para o pino 3 1 2 3 1 2 3 4 5

31 (C) 2008 Gustavo Motta31 6. Comandos iterativos e recursão Recursão Recursão Exemplo: torres de Hanói Exemplo: torres de Hanói Solução Solução Refinamento do passo 1.1.1 Refinamento do passo 1.1.1 1.1.1 Mover 2 discos do pino 1 para o pino 2 1.1.1 Mover 2 discos do pino 1 para o pino 2 1.1.1 Mover 1 disco do pino 1 para o pino 3 1.1.1 Mover 1 disco do pino 1 para o pino 3 1.1.2 Mover o disco 2 do pino 1 para o pino 2 1.1.3 Mover 1 disco do pino 3 para o pino 2 1.1.3 Mover 1 disco do pino 3 para o pino 2 1 2 3 1 2 3 4 5

32 (C) 2008 Gustavo Motta32 6. Comandos iterativos e recursão Recursão Recursão Exemplo: torres de Hanói Exemplo: torres de Hanói Solução Solução Versão generalizada da solução Versão generalizada da solução 1. Caso N > 0 1. Caso N > 0 1.1 Mover os (N – 1) primeiros discos do pino 1 para o pino 2 1.1 Mover os (N – 1) primeiros discos do pino 1 para o pino 2 1.2 Mover o disco N para o pino final 1.2 Mover o disco N para o pino final 1.3 Mover os (N – 1) primeiros discos do pino 2 para o pino 3 1.3 Mover os (N – 1) primeiros discos do pino 2 para o pino 3 1 2 3 1 2 3 4 5

33 (C) 2008 Gustavo Motta33 6. Comandos iterativos e recursão Recursão Recursão Exemplo: torres de Hanói Exemplo: torres de Hanói Solução em Java Solução em Java void torresDeHanói(int númeroDeDiscos, String origem,String destino, void torresDeHanói(int númeroDeDiscos, String origem,String destino, String auxiliar) { String auxiliar) { if (númeroDeDiscos > 0) { if (númeroDeDiscos > 0) { torresDeHanói(númeroDeDiscos - 1,origem,auxiliar,destino); torresDeHanói(númeroDeDiscos - 1,origem,auxiliar,destino); System.out.println("Mover disco "+númeroDeDiscos+ " do "+origem+" para o"+destino); System.out.println("Mover disco "+númeroDeDiscos+ " do "+origem+" para o"+destino); torresDeHanói(númeroDeDiscos - 1,auxiliar,destino,origem); torresDeHanói(númeroDeDiscos - 1,auxiliar,destino,origem); } }

34 (C) 2008 Gustavo Motta34 6. Comandos iterativos e recursão Recursão Recursão Exemplo: torres de Hanói Exemplo: torres de Hanói Solução em Java Solução em Java torresDeHanói(3, "p1","p3","p2") torresDeHanói(3, "p1","p3","p2"), ) N = 3 Origem = p1 Destino = p3 auxiliar = p2 torresDeHanói(2, p1, p2, p3), ) N = 2 Origem = p1 Destino = p2 auxiliar = p3 torresDeHanói(1, p1, p3, p2) N = 1 Origem = p1 Destino = p3 auxiliar = p2 Mover disco 1 de p1 para p3 return, ) return Mover disco 2 de p1 para p2 torresDeHanói(1, p3, p2, p1) return N = 1 Origem = p3 Destino = p2 auxiliar = p1 Mover disco 1 de p3 para p2 return, ) return Mover disco 3 de p1 para p3 torresDeHanói(2, p2, p3, p1) return, ) N = 2 Origem = p2 Destino = p3 auxiliar = p1 torresDeHanói(1, p2, p1, p3), ) return Mover disco 2 de p2 para p3 torresDeHanói(1, p1, p3, p2) return N = 1 Origem = p2 Destino = p1 auxiliar = p3 Mover disco 1 de p2 para p1 return N = 1 Origem = p1 Destino = p3 auxiliar = p2 Mover disco 1 de p1 para p3 return


Carregar ppt "Introdução à Programação Um enfoque orientado a construção de modelos em programas baseados em objetos Gustavo Motta Departamento de Informática - UFPB."

Apresentações semelhantes


Anúncios Google