Pontifícia Universidade Católica de São Paulo Departamento de Ciência da Computação LP: Laboratório de Programação Prof. ISVega Apontamento 11 Abril de 2004 Iteração com Sentinela CONTEÚDO 11.1 Repetição com Sentinela . . . . . . . . . . . . . . 11.1.1Repetição Indefinida while . . . . . . . . . Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 6 Objetivos • Estudar a representação de computações com iterações controladas por sentinela. As estruturas de repetição são utilizadas para descrever situações nas quais os passos de uma computação são repetidos diversas vezes. A quantidade de repetições de cada passo depende do valor produzido pela avaliação de uma expressão condicional. As estruturas de repetição são caracterizadas pelo uso de uma condição para repetir uma computação. Em termos de mapas de execução, este efeito é descrito por uma bifurcação na rota normal de uma computação, conduzindo a um trecho anterior da rota no mapa. A condição pode envolver um contador ou um sentinela. No primeiro caso, trata-se de uma repetição com contador. O segundo caso caracteriza uma repetição com sentinela. 1 Laboratório de Programação Abril de 2004 11.1 Repetição com Sentinela Estruturas contendo a repetição de trechos de rota podem ser elaboradas utilizandose um contador ou um sentinela. O sentinela é um valor que indica o final de uma seqüência de dados. Enquanto este valor da seqüência não for atingido, repetem-se os passos de computação do trecho de rota do ciclo. A quantidade de repetições fica, portanto, dependente de uma condição envolvendo o valor-sentinela. Este padrão estrutural também é conhecido por repetição indefinida. Ou seja, não se conhece, antecipadamente, quando irá surgir o valor-sentinela na seqüência de dados de entrada. A expressão que controla a repetição indefinida pode ser posicionada no início ou no fim do ciclo. Repetições com a expressão-sentinela no início são conhecidas como repetições while. Aquelas com a expressão-sentinela no final do ciclo são conhecidas por repetições do. Uma pode ser transformada na outra, com preservação do resultado da computação descrita. 11.1.1 Repetição Indefinida while Um típico mapa de execução representando uma repetição com sentinela no início do ciclo é mostrado na Figura 11.1. c a [ valor do dado diferente do sentinela ] dado b O valor sentinela indica a continuação ou não do ciclo. Figura 11.1: Estrutura de um mapa de execução com repetição controlada por sentinela no início do ciclo. Percebe-se, neste mapa, a presença dos seguintes pontos importantes: • (i) Obtenção do primeito dado da seqüência. • (ii) Verificação se o valor do dado não corresponde ao valor do sentinela. • (iii) Obtenção do próximo dado da seqüência (como parte do trecho de rota do ciclo). No caso do mapa da Figura 11.1, após o passo de computação indicado por a, obtémse o primeiro dado da seqüência de entrada. Enquanto o valor deste dado for diferente do valor-sentinela, prossegue-se pela trecho que passa pela computação b, e obtém-se o próximo dado de entrada. Quando o valor do dado de entrada for igual c Copyright °1998-2004, Dr. Italo S. Vega 11-2 Laboratório de Programação Abril de 2004 ao valor-sentinela, desvia-se pela bifurcação, em direção ao passo de computação c. Isto encerra o ciclo que cruza o passo b. A descrição de computações com sentinela pode ser feita com o uso de comandos while, segundo o diagrama sintático: CmdWhile DadoInicial ¶ ³ ´ ¶ ³ ¶³ 2: µ while ( µ ´ µ´ NegacaoCondicaoParada ¶³ ¶³ ³ ) { µ´ µ´ ¶ µ ComandosDoCiclo ´ 3: ProximoDado ¶ ³ ´ ¶³ µ} µ´ Tais estruturas podem ser programadas, em Java, segundo o padrão: // passo de computção <a> // obter valor inicial do <dado> while( ! <condição de parada com o valor sentinela> ) { // <-- (2) // passo de computção <b> // obter próximo valor do <dado> // <-- (3) } // passo de computção <c> Construção de Repetições Indefinidas A elaboração de estruturas de repetição indefinidas pode ser realizada segundo o procedimento a seguir: ab bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc 1) Identificar a condição de parada envolvendo o valor-sentinela. d e d e d 2) Construir uma condição negando a condição de parada.e d e Esta é a condição da estrutura de repetição. d e d e d 3) Permitir que a condição de parada se torne verdadeira den-e d e tro do trecho do ciclo. d e d e d e 4) Verificar se o efeito representado pelo mapa corresponde àe d d d execução dos trechos que passam por a, por b (opcional) e por c. e e fgggggggggggggggggggggggggggggggggggggggh c Copyright °1998-2004, Dr. Italo S. Vega 11-3 Laboratório de Programação Exemplo 11.1 A seqüência de 0 1 f (x ) = f (x − 1) + f (x − 2) Abril de 2004 Fibonacci é definida pelas equações: ,x = 0 ,x = 1 ,x > 1 Assim, se x = 2, tem-se: f (2) = f (1) + f (0) = 1 + 0 = 1 No caso de x = 3: f (3) = f (2) + f (1) = 1 + 1 = 2 E, para x = 4: f (4) = f (3) + f (2) = 2 + 1 = 3 O processo de cálculo segue um padrão a cada ciclo: soma dos dois últimos números. Processos desta natureza são conhecidos por processos recursivos. Por um lado, tais processos podem ser utilizados para produzir seqüências infinitas com apenas algumas equações. Por outro lado, não se consegue calcular o n-ésimo número até que se tenha calculado os n números precedentes. Quais os números da seqüência de Fibonacci menores do que 1000? Uma computação organizada ao redor de um while poderia ser elaborada seguindo a estratégia anterioremente proposta: 1) Identificar a condição de parada: (f2 >= 1000) A variável f2 é utilizada na expressão que representa a condição de parada com base no valor-sentinela 1000. 2) Construir uma nova condição negando a condição de parada: (f2<1000) Esta é a expressão que denota a condição de controle da estrutura de repetição. 3) Permitir que a condição de parada se torne verdadeira dentro do trecho do ciclo: (f2 = f1 + f0). 4) Verificar se o efeito representado pelo mapa corresponde à execução dos trechos envolvendo os passos a, b e c. O mapa da Figura 11.2 foi elaborado a partir destas considerações. c Copyright °1998-2004, Dr. Italo S. Vega 11-4 Laboratório de Programação f0 ← 0 f1 ← 1 Abril de 2004 1) Condição de parada: f2 >= 1000 f2 ← f1 + f0 2) Negação da [ f2 < 1000 ] condição de parada : f2 < 1000 f2 : int f2 ← f1 + f0 3) Próximo dado de entrada.. f0 ← f1 f1 ← f2 print( f1 ) 4) Ação a ser repetida. Figura 11.2: Estrutura de um mapa de execução com repetição controlada por sentinela para calculara a seqüência de Fibonacci até 1000. Em termos de Java: hFibonacci.javai≡ public class Fibonacci { public void calcular() { System.out.print(0); int f0 = 0; int f1 = 1; int f2 = f1 + f0; while( f2 < 1000 ) { // <- (2) f0 = f1; f1 = f2; System.out.print( ", " + f1 ); f2 = f1 + f0; // <- (3) } } } A execução deste programa produz: 0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987 ¨ c Copyright °1998-2004, Dr. Italo S. Vega 11-5 Laboratório de Programação Abril de 2004 E XERCÍCIOS 11.1 S EQÜÊNCIA DE F IBONACCI Tarefa 11.1.1 Crie o projeto ex11.1. Tarefa 11.1.2 Crie a classe Fibonacci, conforme mostrado no exemplo 11.1. Tarefa 11.1.3 Crie o objeto fib e envie a mensagem fib.calcular(). Qual o último número da seqüência de Fibonacci mostrado? Tarefa 11.1.4 Acrescente a variável limite:int na classe Fibonacci. Tarefa 11.1.5 Acrescente o método mudarLimite(novo:int):void, reponsável por alterar o valor da variável limite. Tarefa 11.1.6 Altere o método calcular() de modo que a condição de parada seja o valor da variável limite. Tarefa 11.1.7 Crie o objeto fib, envie a mensagem fib.mudarLimite(1000), seguida da mensagem fib.calcular(). A seqüência produzida é igual à anterior? Tarefa 11.1.8 5000? Qual o último número da seqüência quando limite tem o valor 11.2 J OGO DE D ADOS Um determinado jogo consiste de dois dados. O jogador rola os dados e observa os seus valores. Caso a soma destes valores seja exatamente 7, ele ganha; senão ele perde o jogo. Tarefa 11.2.1 Proponha um mapa de execução que simule este jogo de dados. OBS 1: a aplicação deverá mostrar a soma dos dados a cada jogada. Além disso, mostrará :) sempre que ocorrer vitória do jogador, e deverá mostrar :( sempre que o jogador perder. Tarefa 11.2.2 Redesenhe o mapa considerando a existência dos contextos: • Jogo: duas variáveis d1 e d2 da classe Dado, e a descrição do método jogar():void. Este método contém as ativações d1.rolar() e d2.rolar(), seguidas da determinação do resultado do jogo. • Dado: contém a descrição do método rolar():void, que produz um número aleatório entre 1 e 6, armazenando-o na variável interna face:int, que representa o valor de face de um dado. OBS 2: Java oferece a classe Random no pacote java.util com a operação nextFloat(). A cada ativação desta operação, um novo número float é gerado. Este número encontra-se no intervalo [0..1). OBS 3: Java oferece a classe Math com a operação round(numero), que arredonda o seu argumento double. c Copyright °1998-2004, Dr. Italo S. Vega 11-6 Laboratório de Programação Tarefa 11.2.3 Crie o projeto ex11.2. Tarefa 11.2.4 Codifique as classes Jogo e Dado. Abril de 2004 Tarefa 11.2.5 Crie os objetos j:Jogo, d1:Dado e d2:Dado. Envie as mensagens j.mudarD1(d1) e j.mudarD2(d2). Confirme se as variáveis j.d1 e j.d2 apontam para os objetos d1 e d2 criados. Tarefa 11.2.6 Envie a mensagem j.jogar() e verifique se a soma dos valores de face dos dados d1 e d2, conferem com o resultado informado por j. Tarefa 11.2.7 Altere o mapa de execução de modo que o jogador seja informado sobre a quantidade de vezes que ganhou. 11.3 M ÁQUINA C AÇA -N ÍQUEL Desenhe um mapa de execução e codifique em Java uma aplicação que simula uma máquina caça-níquel simples, na qual três números entre 0 e 9 são selecionados aleatoriamente e apresentados lado a lado. Caso os três números sejam iguais, o jogador ganha, senão, ele perde (a aplicação deverá mostrar ":)"ou ":(", respectivamente). (Inspirado em Lewis & Loftus, Java Software Solutions: Foundations of Program Design, 2001, Addison-Wesley.) c Copyright °1998-2004, Dr. Italo S. Vega 11-7