Transcript Comando de repetição
BC & T Universidade Federal do ABC
Estruturas de tipos: repetição estão divididas em três – Estrutura
enquanto
(
while
) – Estrutura
repita
(
do while
) – Estrutura
para
(
for
)
• Quando uma seqüência de comandos deve ser executada usamos repetição.
repetidas uma vezes estrutura de • A estrutura de repetição, assim como a de decisão, envolve sempre a de uma condição.
avaliação • Também conhecidas como laços de repetição ou
loops.
bloco
Um arquivo chamado resultado.txt armazena o resultado final da disciplina de modo que cada linha tem duas colunas, a primeira tem o a número de matrícula de todos os alunos e a segunda coluna situação final do aluno: aprovado ou reprovado. Queremos determinar a quantidade de alunos aprovados.
01222 aprovado 03440 reprovado 01999 aprovado 02113 aprovado 01110 reprovado 12345 aprovado 01010 aprovado 02900 aprovado
Um arquivo chamado resultado.txt armazena o resultado final da disciplina de modo que cada linha tem duas colunas, a primeira tem o a número de matrícula de todos os alunos e a segunda coluna situação final do aluno: aprovado ou reprovado. Queremos determinar a quantidade de alunos aprovados.
Um solução: 1. Se não é fim do arquivo, leia uma linha do arquivo; 2. se a linha corresponde a um aluno aprovado • então incremente o contador de alunos aprovados • senão, volte para o passo 1.
• A estrutura enquanto de repetição permite especificar instruções que devem ser repetida enquanto determinada condição for verdadeira • Exemplo: enquanto não terminar o arquivo, leia linha e incremente contador aprovados se for o caso.
de • O corpo enquanto instrução execução ou da pode um estrutura ser bloco uma de bloco
• Quando a condição da estrutura
enquanto
se tornar falsa, a ação (ou bloco de ações) da estrutura será pulada.
• O programa continuará com a ação imediatamente após a estrutura
enquanto
.
• IMPORTANTE:
loop
infinito.
você deve sempre prever o comando, ou ação, que tornará falsa a condição do
enquanto
, caso comando contrário, seu programa entrará em bloco
Pseudolinguagem
enquanto
condição ?
F V
bloco
início
Leonardo de Pisa (ou Fibonacci, 1170 - 1250) descreveu o crescimento de uma população de coelhos por uma sequência de números que agora é conhecida por sequência de Fibonacci: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...
Essa sequência é definida por F(1) = F(2) = 1 e se n > 2 então F(n) = F(n-1) + F(n-2).
Dado um inteiro n>0, obter F(n), o n ésimo número de Fibonacci.
Esboço de uma solução: 1. Dado n; 2. se n=1 ou n=2, 3.
então responda “F(n)=1”; senão, tome i igual a 2 e faça 3.2. i ← i+1; 3.3. F(i) ← F(i-1) + F(i-2); 3.4. se i Obs: A linha 3.1 é executada apenas uma vez e a linha 3.3 aumenta o valor da laço termina pois a condição na linha 3.4 torna-se falsa. Exercício: variável i até que i=n e, nesse caso, o Resolver usando enquanto . Algoritmo Fibonacci inicio inteiro n, a, b, prox, cont; leia (n); a ← b ← 1; se ( n=1 n=2 ) entao inicio escreva (b); fimentao senao inicio cont ← 2; enquanto ( cont <> n ) inicio prox a ← a + b; ← b; b ← prox; cont ← cont + 1; faça fimenquanto fimsenao escreva(b); fimalgoritmo. Sabe-se que um soma de n número inteiro positivo da forma n³ é a números ímpares conscutivos. Por exemplo, 1^3 = 1 2^3 = 3+5 3^3 = 7+9+11 4^3 = 13+15+17+19, ... n^3 = k + (k+2) + (k+4) + ... + (k+2(n -1)), para algum k ímpar. Dado um inteiro n>0, determinar k tal que como soma de n n³ pode ser escrito ímpares consecutivos como descrito acima. Esboço de uma solução: 1. leia(n) 2. k=1; 3. soma = k + (k+2) + (k+4)+ ... + (k + 2(n -1)), para algum k; 4. se (soma = n ³) então achou, responda k; 5. senão incrementa k de 2 e volta pra linha 3. Problema : Como avaliar k + (k+2) + (k+4)+ ... + (k + 2(n -1))? Como avaliar k + (k+2) + ... + (k + 2(n -1))? Outro laço: 1. dado k, dado n e inicializadas com 0 as 2. enquanto i <= 2(n-1) 2.1. soma faça ← soma + (k + i); 2.2. i← i+2; variáveis i e soma; Algoritmo Cubo como soma de ímpares consecutivos início inteiro: n, soma, k, i; lógico: achou; leia ( n ); // n>=1 achou ← falso; k ← 1; enquanto ( ~achou ) faça inicio i ← soma ← 0; enquanto ( i < 2*n ) faça inicio soma ← soma + (k + i); i ← i + 2; fimenquanto se ( soma = n^3 ) entao inicio achou ← verdadeiro; fimentao senao inicio k ← k + 2; fimsenao fimenquanto escreva(k); fimalgoritmo Características de funcionamento: Não é necessário o conhecimento prévio do número de repetições • Executa a repetição enquanto a condição for verdadeira, testando-a desde seu início • Os comandos do loop podem não ser executados instruções Validação inicial enquanto • O que indica quantas vezes uma repetição será realizada? • A estrutura enquanto não oferece este recurso. • Solução: uso de um contador, que tem um certo valor inicial ou variável contadora, (atribuído fora do laço) e é incrementada a cada repetição. • Exemplo de contador: inteiro cont; // declaração do contador cont 0; // inicialização do contador cont cont + 1; // incrementa contador em uma unidade • O que indica quantas vezes uma repetição será realizada? • A estrutura enquanto não oferece este recurso. • Solução: uso de um contador, ou variável contadora, incrementada a cada repetição. (atribuído fora do laço) e é • Exemplo de contador: Laço de Repetição realize o que se pede. Isto é responsabilidade do programador!!! cont cont + 1; // incrementa contador em uma unidade i ← 0; enquanto ( i < 2*n ) faça inicio soma ← soma + (k + i); i ← i + 2; fimenquanto cont ← 2; enquanto ( cont <> n ) faça inicio prox ← a + b; a ← b; b ← prox; cont ← cont + 1; fimenquanto • Valor de sentinela (finalizador, de sinal ou de flag ) valor especial que indica o final de entrada de dados. – Usado pelo repetição. usuário para indicar final do laço de • Exemplo: se a entrada de um problema é um sequência de inteiros positivos podemos usar -1 como sinal de fim da entrada. Uso do sentinela para indicar o fim da entrada de dados: Escreva um algoritmo que determine se números inteiros e positivos são pares, ou ímpares. Utilize a estrutura para permitir a entrada da seqüência de números. O último número, que não será considerado na análise, deve assumir o valor –1 (sentinela). Algoritmo ParImpar início inteiro: valor, resto; string: mensagem; leia ( valor ); enquanto ( valor resto –1 ) faça valor mod 2; se ( resto=0 ) então inicio mensagem fimentao “Número par”; senão inicio mensagem fimsenao escreva( mensagem); “Número ímpar”; leia ( valor ); fimenquanto fimalgoritmo • Outro exemplo: em computação EOF é uma condição que indica fim-de-arquivo (End-Of-File). Concretamente, é um flag cujo valor de fato depende do sistema operacional e que não corresponde a um carater válido, usualmente é -1. Um arquivo chamado resultado.txt armazena o resultado final da disciplina de modo que cada linha tem duas colunas, a primeira tem o número de matrícula de todos os alunos e a segunda coluna a situação final do aluno: aprovado ou reprovado. Queremos determinar a quantidade de alunos aprovados. 01222 aprovado 03440 reprovado 01999 aprovado 02113 aprovado 01110 reprovado 12345 aprovado 01010 aprovado 02900 aprovado String: linha; inteiro: aprovados; aprovados ← 0; enquanto (~EOF(resultado.txt)) faça inicio leia (linha); se (linha termina em “aprovado”) inicio aprovados ← aprovados + 1; fimse fimenquanto escreva(aprovados); fimalgoritmo Obs.: EOF = “End Of File” = “Fim de Arquivo” Pseudolinguagem enquanto JAVA // Não é padrão while // Padrão com {} while Algumas linguagens (Ex.: Java, C#, C++, C) contém operadores especiais para simplificar a atribuição de valores às variáveis As Estruturas de Repetição demandam o uso frequente de operadores associados às variáveis de controle Portanto, recomenda-se usar os seguintes operadores em Java (seja i uma variával): i++; ou ++i;: Se colocado sozinho em uma linha, equivale ao comando: i = i + 1; No caso de contador: adiciona 1 ao valor do contador i--; ou --i;: Se colocado sozinho em uma linha, equivale ao comando: i = i - 1; No caso de contador: subtrai 1 do valor do contador Para o caso de existir mais de um comando na mesma linha em que estes operadores, a colocação de “++” (ou “--”) antes ou depois da variável define a ordem em que as operações serão executadas. Em laços de repetição, deve-se usar “ i++ ” ou “ i —” . i+=b; Equivale ao comando: i = i + b; i-=b; Equivale ao comando: i = i - b; i*=b; Equivale ao comando: i = i * b; i/=b; Equivale ao comando: i = i / b; import java.io.*; import java.util.*; public class resultado { public static void main(String[] args) throws FileNotFoundException { String linha, arquivo="resultado.txt"; Scanner sc = new Scanner(new File(arquivo)); int aprovados = 0, total = 0; while ( sc.hasNext() ) { total = total + 1; //computa o numero de alunos linha = sc.nextLine() ; if ( linha.endsWith("aprovado") ){ aprovados = aprovados + 1; } } System.out.println("número de alunos matriculados: " + total); System.out.println("número de alunos aprovados: " + aprovados); System.out.println("número de alunos reprovados: " + (total aprovados)); }//fim do main }//fim da classe import java.util.*; public class fibonacci { public static void main (String[] args) { Scanner s = new Scanner(System.in); int n=0, a=1, b=1, cont=2, prox=0; System.out.print("Entre n: "); n = s.nextInt(); if ( n==1 || n==2 ) System.out.println( "F("+n+")="+b ); else { while ( cont != n ) { prox = a + b; a = b; b = prox; cont = cont + 1; } } System.out.println("F("+n+")="+b); }//fim do main }// fim da classe import java.util.*; public class cuboXsoma { public static void main (String[] args) { Scanner s = new Scanner(System.in); int n, soma, k, i; boolean achou=false; // achou o valor de k? System.out.print("Entre n: "); n = s.nextInt(); int cubo = n*n*n; //soma == cubo economiza operações comparado com //soma == n*n*n no condicional abaixo k=1; //primero ímpar while ( !achou ) {// enquanto não achou i=0; soma = 0; while ( i < 2*n ) { // avalia k + (k+2) + ...+(k + 2(n-1)) soma = soma + ( k + i ); i = i+2; } if (soma == cubo) { achou = true;} else {k = k+2;} // tome o próximo ímpar } System.out.println("k = " + k); }//fim do main }fim da classe • • Implemente um jogo de dados que: • O jogador inicie o jogo com R$ 100,00 A cada jogada, o jogador jogue dois dados Se a soma dos números dos dados for 7 ou 11, o jogador recebe o dobro do que tenha apostado no momento • Se a soma dos números não for 7 ou 11, o jogador perde R$ 20,00 • O jogo acaba quando o saldo do jogador for menor ou igual a zero. Ou então quando o jogador decidir parar • Ao final, escreva o total de dinheiro que o jogador tem, e quantas vezes ele ganhou e quantas vezes perdeu no jogo Algoritmo JogoDeDados início real: dinheiro, aposta; inteiro: dado1, dado2, soma, numVitoria, numDerrota; string: continua; dinheiro 100,00; numVitoria = 0; numDerrota = 0; escreva( “Deseja jogar?” ); leia ( continua ); enquanto ( (continua = “S”) faça (dinheiro > 0) ) leia ( aposta ); dado1 dado2 randomico(1..6); randomico(1..6); soma dado1 + dado2; se ( (soma = 7) (soma = 11) ) então numVitoria dinheiro numVitoria + 1; dinheiro + 2*aposta; senão numDerrota dinheiro numDerrota + 1; dinheiro - 20; escreva( “Deseja jogar?” ); leia ( continua ); fimenquanto escreva( numVitoria ); escreva( numDerrota ); escreva( dinheiro ); fimalgoritmo import java.util.*; public class JogoDados { public static void main(String[] args) { double dinheiro, aposta; int dado1, dado2, soma, numVitoria, numDerrota; String continua = null; dinheiro = 100.00; numVitoria = 0; numDerrota = 0; Scanner s = new Scanner(System.in); Scanner n = new Scanner(System.in); System.out.print("Deseja jogar? (s/n)"); continua = s.nextLine(); while ( continua.equals("s") && dinheiro > 0 ) { System.out.print("Digite sua aposta: "); aposta = n.nextDouble(); Random num = new Random(); dado1 = num.nextInt( 5 ) + 1; dado2 = num.nextInt( 5 ) + 1; soma = dado1 + dado2; System.out.print(" Dado 1 = " + dado1); System.out.println(" Dado 2 = " + dado2); if ( soma == 7 || soma == 11 ){ numVitoria = numVitoria + 1; dinheiro = dinheiro + 2*aposta; System.out.println("Vitorias = " + numVitoria); System.out.println(" Dinheiro = " + dinheiro); }// fim if else{ numDerrota = numDerrota + 1; dinheiro = dinheiro - 20; System.out.println("Derrotas = " + numDerrota); System.out.println("Dinheiro="+dinheiro); }//fim else System.out.print("Deseja jogar? (s/n)"); continua = s.nextLine(); } //fim while } // fim método } // fim da classe Estruturas de repetição: – Estrutura ( ) – Estrutura ( ) • Para realizar a repetição com teste no final deve ser utilizado a estrutura uma repita, ação (ou executada determina verdadeira. que permite bloco) enquanto condição ser uma seja • Exemplo: soma nota, enquanto número de notas for menor que 10. • O corpo da estrutura pode ser uma repita instrução única, ou um bloco de comandos Repita bloco F V Pseudocódigo repita Bloco de Execução enquanto condição ? F V Reescrevendo a solução para números de Fibonacci 1. Dado n; 2. se n=1 ou n=2, 3. então responda “F(n)=1”; senão, tome i igual a 2 e faça 3.2. i ← i+1; 3.3. F(i) ← F(i-1) + F(i-2); 3.4. se i Obs: Se n>2 então as linhas 3.2, 3.3 e 3.4 serão executadas pelo menos uma vez. Algoritmo Fibonacci_v2 inicio inteiro n, a, b, prox, cont; leia (n); a ← b ← 1; se ( n=1 n=2 ) entao inicio escreva (b); fimentao senao inicio cont ← 2; repita inicio prox a ← a + b; ← b; b ← prox; cont ← cont + 1; fim enquanto (i<>n); fimsenao escreva(b); fimalgoritmo. Pseudocódigo repita Java // Não é padrão do comando; while ( condição ) ; Java // Padrão: com { } do { comandos; } while ( condição ) ; • Tem a mesma função que o laço while , só que o teste só é feito no final • Pelo menos uma vez os comandos serão executados • Note que, no do...while , o uso do “;” após a condição é obrigatório A mesma observação vale no exemplo 3. Queremos avaliar k + (k+2) + ... + (k + 2(n -1)). A solução foi: 1. dados k e n; 2. i ← 0; 3. soma ← 0; 4. enquanto i <= 2(n-1) 4.1 soma ← soma + (k + i); 4.2 i← i+2; Como n >= 1 o primeiro teste de Exercício: Reescreva o “i<=2(n-1)” sempre valerá. pseudocódigo do exemplo 3 usando repita-enquanto no laço mais interno. Algoritmo Cubo como soma de ímpares consecutivos início inteiro: n, soma, k, i; lógico: achou; leia ( n ); // n>=1 achou ← falso; k ← 1; enquanto ( ~achou ) faça inicio i ← soma ← 0; repita inicio soma ← soma + (k + i); i ← i + 2; fim enquanto (i < 2*n); se ( soma = n^3 ) entao inicio achou ← verdadeiro; fimentao senao inicio k ← k + 2; fimsenao fimenquanto escreva(k); fimalgoritmo Estruturas de repetição: – Estrutura ( ) – Estrutura ( ) • Executa o bloco de predeterminado de vezes; instruções um Pseudocódigo para V de vi até vf passo p faça sim limite ? não No exemplo 3, queremos avaliar k + (k+2) + ... + (k + 2(n -1)). Usando a código como instrução para, podemos reescrever o pseudo soma ← 0; para i de 0 até 2*(n-1) passo 2 faça inicio soma fimpara ← soma + (k+i); Exercício: Escreva um algoritmo em pseudocódigo que recebe dois inteiros positivos, digamos k e n, e devole a soma dos n primeiros múltiplos de 5 maiores ou iguais a k. Pseudocódigo para V de vi até vf passo p faça Java // Não é padrão for (V = vi; V <= vf; V = V + passo) comando; Java // Padrão: com { } for (V = vi; V <= vf; V = V + passo) comando; 1. Usando as três opções de estruturas de repetição, resolva os exercícios a seguir sem alterar o código entre { } abaixo: { System.out.print (“i=” + i + “\t”); } Imprimir os números: Entre 1 e 10, inclusive (vale para todos os itens a seguir), em ordem crescente Entre 0 e 10, em ordem crescente Entre 0 e 20, em ordem crescente Pares entre 0 e 20, em ordem crescente Ímpares entre 0 e 20, em ordem crescente Entre 0 e 20, em ordem crescente e variando de 3 em 3 números Entre 0 e 20, em ordem crescente e variando de 5 em 5 números Entre 10 e 1, em ordem decrescente Entre 20 e 0, em ordem decrescente Pares entre 20 e 0, em ordem decrescente Entre 20 e 0, em ordem decrescente e variando de 4 em 4 números • FORBELLONE, A. L. V.; EBERSPACHER, H. F., Lógica de Programação – A Construção de Algoritmos e Estruturas de Dados, Prentice Hall, 2005 • Deitel, H. M. e Deitel, P. J.; Pearson Prentice-Hall, 2005 JAVA – Como Programar ; 6 ª edição, EditoraUsamos i no exemplo 3:
Usamos cont no exemplo 2:
enquanto
Existem ainda operadores em Java para outras operações aritméticas (sejam i e b duas variáveis):
Estes operadores são menos utilizados, mas i++; e
i--; são muito comuns na programação em Java!
enquanto
while
–Estrutura repita ( do while )
para
for
enquanto
while
repita
do while
–Estrutura para ( for )