A maior rede de estudos do Brasil

Grátis
259 pág.
apostila

Pré-visualização | Página 14 de 50

DENTRO DE REPETIC¸O˜ES 59
positivos, ignorando os negativos ou nulos.
Se o enunciado fosse simplesmente para ler e imprimir 30 nu´meros, como far´ıamos?
Provavelmente como ilustrado na figura 6.6. Observamos que este problema e´ muito
similar a outros ja´ estudados no cap´ıtulo anterior. Trata-se de um lac¸o que precisa de
um contador para se determinar a sa´ıda.
program lereimprimir ;
var i , a : integer ; (∗ i serve para contar quantos numeros foram lidos ∗)
begin
i := 1;
while i <= 30 do
begin
read (a) ;
writeln (a) ;
i := i + 1;
end;
end.
Figura 6.6: Lendo e imprimindo 30 nu´meros.
O problema e´ que na˜o queremos imprimir todos os nu´meros lidos, mas apenas
aqueles que sa˜o positivos: se o nu´mero lido for positivo, enta˜o queremos imprimir,
sena˜o na˜o. Conforme ja´ visto, o comando if faz exatamente isto, testa uma expressa˜o
booleana que, caso satisfeita, executa o comando subsequente, sena˜o o pula, passando
diretamente para o seguinte, tal como ilustrado na figura 6.7.
program lereimprimir ;
var i , a : integer ;
begin
i := 1;
while i <= 30 do
begin
read (a) ;
i f a > 0 then
writeln (a) ; (∗ so eh executado quando a eh positivo ∗)
i := i + 1;
end;
end.
Figura 6.7: Lendo e imprimindo os positivos apenas.
Relembrando, o comando de desvio condicional tambe´m permite executar exclu-
sivamente uma ac¸a˜o alternativa, caso o teste da expressa˜o booleana resulte em falso.
Por exemplo, se o enunciado fosse “ler 30 nu´meros e imprimir os que sa˜o pares mas
imprimir o quadrado dos que na˜o sa˜o, incluindo o zero”.
60 CAPI´TULO 6. TE´CNICAS ELEMENTARES
Do ponto de vista lo´gico, seria o mesmo que dizer o seguinte: “se o nu´mero lido for
positivo, imprimı´-lo, caso contra´rio ele e´ zero ou negativo, enta˜o imprimir o quadrado
dele”. Isto pode ser visto na figura 6.8. Destacamos mais uma vez que a estrutura
de controle do lac¸o na˜o mudou, apenas os comandos que sa˜o executados no lac¸o
mudaram, caracterizando-se dois subproblemas: um para controlar o lac¸o, outro para
se decidir se o nu´mero e´ positivo ou na˜o e o que fazer com ele.
program lereimprimir ;
var i , a : integer ;
begin
i := 1;
while i <= 30 do
begin
read (a) ;
i f a > 0 then
writeln (a) (∗ so eh executado quando a for positivo ∗)
else
writeln (a∗a) ; (∗ so eh executado quando a <= 0 ∗)
i := i + 1;
end;
end.
Figura 6.8: Lendo e imprimindo os positivos e os quadrados dos ı´mpares.
Agora, o comando que imprime a so´ e´ executado quando a > 0. Se isto na˜o for
verdade, o que e´ impresso e´ o quadrado de a. Em ambos os casos o valor de i e´
incrementado.
Este u´ltimo programa pode facilmente ser modificado para se resolver o problema
de se contar quantos nu´meros lidos sa˜o positivos e quantos na˜o sa˜o. Basta, ao inve´s
de imprimir, contar, ou em outras palavras, acumular.
Para isto sa˜o necessa´rias duas varia´veis adicionais, que iniciam em zero e que sa˜o
incrementadas a cada vez que um nu´mero e´ identificado como positivo ou na˜o. Esta
ideia pode ser vista na figura 6.9. Importante notar a similaridade das duas soluc¸o˜es.
Os problemas sa˜o ligeiramente diferentes, eles diferem em um dos subproblemas ape-
nas: um deve imprimir, o outro deve acumular. Os outros problemas tais como o
controle do lac¸o e a leitura dos dados sa˜o exatamente os mesmos problemas.
Podemos usar o mesmo racioc´ınio para resolver toda uma classe de problemas
similares, isto e´, imprimir a soma de nu´meros que satisfazem alguma propriedade.
No caso do problema anterior, a propriedade era “ser negativo” ou “ser positivo”.
Mas poderia ser qualquer outra coisa, como por exemplo “ser diferente de zero”, “ser
primo”, “ser mu´ltiplo de 50” ou algo mais complexo como “ter saldo positivo nos
u´ltimos 12 meses e na˜o estar devendo para o imposto de renda”.
Vejamos um problema similar para uma propriedade simples, cuja soluc¸a˜o pode
ser facilmente adaptada do algoritmo anterior.
6.3. DESVIOS CONDICIONAIS DENTRO DE REPETIC¸O˜ES 61
program contar ;
var i , (∗ serve para contar ate 30 ∗)
conta positivos , (∗ serve para contar os positivos ∗)
conta outros , (∗ serve para contar os nao positivos ∗)
a: integer ; (∗ numeros lidos na entrada ∗)
begin
conta positivos:= 0; (∗ eh preciso inicializar a variavel ∗)
conta outros:= 0;
i := 1;
while i <= 30 do
begin
read (a) ;
i f a > 0 then
conta positivos:= conta positivos + 1
else
conta outros:= conta outros + 1;
i:= i + 1;
end;
writeln (’A quantidade de positivos lidos eh ’ , conta positivos) ;
writeln (’A quantidade de nao positivos lidos eh ’ , conta outros) ;
end.
Figura 6.9: Contando os positivos e os negativos e nulos.
6.3.2 Somando pares e ı´mpares
Problema: Ler uma sequeˆncia de nu´meros e imprimir separadamente a soma dos
que sa˜o pares e a soma dos que sa˜o ı´mpares. O programa deve terminar quando o
nu´mero lido for o zero. Este u´ltimo nu´mero tambe´m deve ser ignorado.
No programa ilustrado na figura 6.10, basicamente foi colocado no lugar do if
x > 0 then a traduc¸a˜o da expressa˜o if “x e´ par” then, traduc¸a˜o esta que envolve o uso
da operac¸a˜o de resto de divisa˜o inteira. Todo nu´mero que, dividido por 2, resulta em
resto 0 so´ pode ser par. Caso contra´rio e´ ı´mpar. Tambe´m foi feita uma mudanc¸a no
nome das varia´veis para facilitar a compreensa˜o do co´digo.
A propriedade pode ser ta˜o complexa quanto se queira, mas e´ importante observar
que o co´digo de base na˜o muda muito. Observe que ha´ uma leitura, o teste, algum
processamento e, por u´ltimo, a leitura do pro´ximo valor, repetindo-se o co´digo.
Problema: Ler nu´meros do teclado, ate´ ler um zero, e imprimir apenas os que sa˜o
ao mesmo tempo mu´ltiplos de 7 mas na˜o sa˜o mu´ltiplos de 2.
Soluc¸a˜o similar (apresentada na figura 6.11). Um lac¸o controla o te´rmino da
repetic¸a˜o, e um desvio condicional verifica a propriedade e algum co´digo e´ executado
em seguida (no caso uma simples impressa˜o na tela).
62 CAPI´TULO 6. TE´CNICAS ELEMENTARES
program somapareseimpares ;
var x, somapares , somaimpares: integer ;
begin
somapares:= 0;
somaimpares:= 0;
read (x) ;
while x <> 0 do
begin
if x mod 2 = 0 then (∗ verdadeiro quando x eh par ∗)
somapares:= somapares + x
else
somaimpares:= somaimpares + x;
read (x) ;
end;
writeln (somapares , somaimpares) ;
end.
Figura 6.10: Soma pares e ı´mpares.
program somaquadradosperfeitos ;
var a: integer ;
begin
read (a) ;
while a <> 0 do
begin
if (a mod 7 = 0) AND (a mod 2 <> 0) then
writeln (a) ;
read (a) ;
end;
end.
Figura 6.11: Imprime os mu´ltiplos de 7 que na˜o sa˜o mu´ltiplos de 2.
Um terceiro problema similar e´ apresentado a seguir.
Problema: Ler nu´meros do teclado, ate´ ler um zero, e imprimir apenas os que forem
mu´ltiplos de 3 maiores do que 50 e menores ou iguais a 201.
Novamente, mesmo racioc´ınio (soluc¸a˜o na figura 6.12). Apenas a propriedade a
ser satisfeita e´ mais complexa, envolve uma expressa˜o booleana contendo conectivos
de conjunc¸a˜o. E´ importante para o estudante comparar os treˆs u´ltimos co´digos e
perceber a enorme similaridade entre eles.
6.3.3 Convertendo para bina´rio
Este problema e´ um desafio que pode ser resolvido com a mesma ideia de se aninhar
um desvio condicional sob o escopo de uma repetic¸a˜o, combinada com o uso dos
6.3. DESVIOS CONDICIONAIS DENTRO DE REPETIC¸O˜ES 63
program somaquadradosperfeitos ;
var a: integer ;
begin
read (a) ;
while a <> 0 do
begin
if (a mod 3 = 0) AND (a > 50) AND (a <= 201) then
writeln (a) ;
read (a) ;
end;
end.
Figura 6.12: Imprime os mu´ltiplos de 3 lidos entre 51 e 201.
acumuladores.
Problema: Dado um nu´mero inteiro entre 0 e 255 imprimir este nu´mero em seu
formato bina´rio.
Este e´ um exemplo cla´ssico em que o estudante esquece da teoria. Tradicional-
mente, o professor apresenta a definic¸a˜o de nu´meros bina´rios,