apostila
259 pág.

apostila

Disciplina:Algoritmos e Estrutura de Dados I542 materiais7.956 seguidores
Pré-visualização50 páginas
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,