a 110 e os sala´rios variam de zero a 19.000,00 unidades da moeda local (sala´rio do seu dirigente ma´ximo). As faixas salariais de interesse sa˜o as seguintes: • de 0 a 3 sala´rios mı´nimos • de 4 a 9 sala´rios mı´nimos • de 10 a 20 sala´rios mı´nimos • acima de 20 sala´rios mı´nimos. Sendo o sala´rio mı´nimo igual a 450,00 unidades da moeda local. Fac¸a um programa em Pascal que leia o arquivo de entrada e produza como sa´ıda os percentuais da populac¸a˜o para cada faixa salarial de interesse. 29. Aqui temos uma forma peculiar de realizar uma multiplicac¸a˜o entre dois nu´meros: multiplique o primeiro por 2 e divida o segundo por 2 ate´ que o primeiro seja reduzido a 1. Toda vez que o primeiro for impar, lembre-se do segundo. Na˜o considere qualquer frac¸a˜o durante o processo. O produto dos dois nu´meros e´ igual a soma dos nu´meros que foram lembrados. Exemplo: 53× 26 = 53 26 13 6 3 1 26 52 104 208 416 832 26 + 104 + 416 + 832 = 1378 Fac¸a uma func¸a˜o em Pascal que receba dois reais e retorne a multiplicac¸a˜o dos dois, do modo como foi especificado acima. Na˜o e´ permitido uso de array. 30. Fac¸a um programa em Pascal que some duas horas. A entrada deve ser feita da seguinte maneira: 12 52 7 13 A sa´ıda deve ser assim: 12:52 + 7:13 = 20:05 Cap´ıtulo 6 Te´cnicas elementares O objetivo deste cap´ıtulo e´ o domı´nio por parte do estudante das principais estruturas de controle de fluxo, em particular quando usadas de maneira combinada: atribuic¸a˜o; entrada e sa´ıda; desvio condicional e repetic¸a˜o, ale´m do uso de expresso˜es. 6.1 Atribuic¸o˜es dentro de repetic¸o˜es Nesta sec¸a˜o veremos exemplos de problemas cujas soluc¸o˜es algor´ıtmicas requerem o uso de atribuic¸o˜es aninhadas em repetic¸o˜es. 6.1.1 Somando nu´meros O problema abaixo servira´ para discutirmos va´rias maneiras de se resolver um mesmo problema ate´ chegarmos na maneira mais elegante. Aproveitamos para discutir a te´cnica dos acumuladores. Problema: Ler 5 nu´meros positivos do teclado e imprimir a soma deles. A primeira e mais simples soluc¸a˜o consiste em ler os 5 nu´meros do teclado e em seguida imprimir a soma deles. O programa da figura 6.1 mostra o algoritmo implementado para esta primeira proposta. program soma valores ; var a1, a2, a3 , a4, a5: integer ; begin read (a1, a2, a3, a4, a5) ; writeln (a1 + a2 + a3 + a4 + a5) ; end. Figura 6.1: Primeira soluc¸a˜o. 55 56 CAPI´TULO 6. TE´CNICAS ELEMENTARES O programa funciona e atende ao requisitado no enunciado. Mas a soluc¸a˜o na˜o e´ boa. Imagine que fosse pedido a soma na˜o de 5 nu´meros, mas de 50. Para manter a mesma ideia do algoritmo anterior, ter´ıamos que escrever algo como ilustrado na figura 6.2. program soma valores 50 ; var a1, a2, a3 , a4, a5, a6, a7, a8 , a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, a50: integer ; begin read (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, a50) ; writeln (a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20 + a21 + a22 + a23 + a24 + a25 + a26 + a27 + a28 + a29 + a30 + a31 + a32 + a33 + a34 + a35 + a36 + a37 + a38 + a39 + a40 + a41 + a42 + a43 + a44 + a45 + a46 + a47 + a48 + a49 + a50) ; end. Figura 6.2: Imprimindo a soma de 50 nu´meros lidos no teclado. E´ o´bvio que esta te´cnica na˜o e´ adequada. Ale´m disto, so´ pode ser usada quando se sabe quantos nu´meros sera˜o fornecidos. Para o problema abaixo, o algoritmo na˜o pode ser usado. Problema: Ler uma sequeˆncia de nu´meros positivos do teclado e imprimir a soma deles. O programa deve terminar quando o nu´mero lido do teclado for zero. Como usar uma varia´vel para cada valor lido? Uma vez que na˜o se sabe, a princ´ıpio, quantos nu´meros sera˜o digitados, na˜o ha´ como fazer isto. Logo, a te´cnica de soluc¸a˜o na˜o pode ser esta. O algoritmo apresentado na figura 6.3 faz uso de uma te´cnica elementar em pro- gramac¸a˜o que e´ o uso de acumuladores. Conve´m observar que a parte do algoritmo relativa a entrada de dados controlada pelo lac¸o ja´ foi estudada no cap´ıtulo anterior. Desta forma, se eliminarmos todas as linhas que conte´m a varia´vel soma o que teremos e´ um programa que leˆ va´rios nu´meros do teclado ate´ que seja lido um zero. O programa na˜o faria nada com os nu´meros lidos. Usa-se uma varia´vel (soma) cujo papel e´ acumular valores, isto e´, a varia´vel e´ inicializada com um valor nulo e na sequeˆncia, ela e´ atualizada para os outros valores a` medida em que eles sa˜o lidos do teclado. A inicializac¸a˜o do acumulador com o valor zero deve-se ao fato deste ser o elemento 6.2. DESVIOS CONDICIONAIS ANINHADOS 57 neutro da adic¸a˜o. Se fosse uma multiplicac¸a˜o de va´rios nu´meros, o acumulador deveria ser inicializado com o elemento neutro da multiplicac¸a˜o, isto e´, o 1. program soma valores ; var numero, soma: integer ; begin soma:= 0; (∗ inicializa o acumulador ∗) read (numero) ; while numero <> 0 do begin soma:= soma + numero; (∗ atualiza o acumulador ∗) read (numero) ; end; end. Figura 6.3: Te´cnica do acumulador. Na figura 6.4 mostra-se como resolver o problema inicial usando a te´cnica dos acumuladores. Notem que a soluc¸a˜o explora um comando de atribuic¸a˜o sob o escopo de um comando de repetic¸a˜o. Trocando-se o valor da constante MAX de 5 para 50, tem-se a soluc¸a˜o para o problema 2. E´ fa´cil perceber que esta maneira e´ gene´rica, resolve problemas similares para qualquer tamanho de entrada, bastando-se trocar o valor da constante MAX. program soma valores ; const max=5; var numero, i , soma: integer ; begin soma:= 0; i:= 1; while i <= max do begin read (numero) ; soma:= soma + numero; end; end. Figura 6.4: Soluc¸a˜o para o primeiro problema com acumuladores. 6.2 Desvios condicionais aninhados O problema a seguir nos permitira´ apresentar um algoritmo que o resolve de maneira elegante atrave´s do uso de estruturas contendo aninhamentos de desvios condicionais. 58 CAPI´TULO 6. TE´CNICAS ELEMENTARES 6.2.1 O menor de treˆs Problema: Apo´s ler treˆs nu´meros no teclado, imprimir o menor deles. A soluc¸a˜o para este problema (figura 6.5) envolve uma se´rie de tomada de deciso˜es com diversos fluxos alternativos de co´digo. Quando um comando esta´ sob o controle de outro, diz-se que o comando mais interno esta´ sob o escopo do mais externo. Neste caso, vamos usar um desvio condici- onal que controla outro. No jarga˜o dos programadores, se diz que os comandos nesta forma esta˜o aninhados. program imprime menor; var a, b, c : integer ; begin write(’entre com tres numeros inteiros: ’) ; read(a , b, c) ; i f a < b then if a < c then writeln (’o menor dos tres eh ’ ,a) else writeln (’o menor dos tres eh ’ ,c) else if b < c then writeln (’o menor dos tres eh ’ ,b) else writeln (’o menor dos tres eh ’ ,c) end. Figura 6.5: Imprimir o menor dentre 3 nu´meros lidos. 6.3 Desvios condicionais dentro de repetic¸o˜es Nesta sec¸a˜o veremos exemplos de problemas cujas soluc¸o˜es algor´ıtmicas requerem o uso de atribuic¸o˜es aninhadas em repetic¸o˜es. 6.3.1 Imprimir apenas nu´meros positivos Neste problema estudaremos como aninhar um comando de desvio condicional dentro do escopo de um comando de repetic¸a˜o. Tambe´m aproveitaremos para iniciar o estudo sobre como pensar no problema global e nos poss´ıveis subproblemas existentes. Problema: Ler do teclado 30 nu´meros inteiros e imprimir na tela aqueles que sa˜o 6.3. DESVIOS CONDICIONAIS