Escolar Documentos
Profissional Documentos
Cultura Documentos
Computational Thinking - Cap 2 - Tomada de Decisão - RevFinal
Computational Thinking - Cap 2 - Tomada de Decisão - RevFinal
santos.anacaraujo@gmail.com
Tomada de decisão Página 2
LISTA DE FIGURAS
LISTA DE QUADROS
LISTA DE TABELAS
SUMÁRIO
2 TOMADA DE DECISÃO
Ao ler o capítulo anterior, podemos concluir que nossos algoritmos “fluem” bem,
mas não conseguem “lidar” com problemas. Ora, a vida real é repleta deles, portanto,
nossos algoritmos em algum momento precisarão lidar com isso.
Por exemplo, embora toda adição de números inteiros apresente uma solução
(x = a + b, onde “a” e “b” são números conhecidos), isso não ocorre nas equações de
primeiro ou de segundo grau. Nas equações de primeiro grau (ax + b = 0), notamos
que o fator (a variável “a”) que multiplica nossa incógnita (a variável “x”) jamais poderá
ser zero, pois não temos solução para divisões por zero.
Se o algoritmo for criado sem levar isso em consideração, irá parar pela
execução de um erro, no caso, uma divisão por zero. Neste caso, ao invés de
calcularmos e apresentarmos uma solução, deveríamos indicar que não há solução,
evitando assim a ocorrência do erro! Basta uma tomada de decisão bem pensada,
para resolver essa inconveniente situação.
Em nossa vida, tomamos decisões o tempo todo. Até dizemos, quando existem
muitas hipóteses a serem analisadas “e se isso?” Ou “e se aquilo?”. Vamos nos deter
nessa pequena, mas fundamental palavra quando se pensa em programação: se.
2.1.1 A INSTRUÇÃO SE
< 0: exibiremos a mensagem que não existem raízes reais para a equação.
Por outro lado, quando a situação analisada é falsa, adota-se a linha do senão.
Figura 2.5 – Estrutura SE em Pascal com mais de uma instrução por bloco
Fonte: Elaborado pelo autor (2015)
Não é tão simples notar, mas antes da palavra “else” (senão) em Pascal, nunca
se usa o terminador (ponto e vírgula), pois a instrução “se” só termina, se tiver “senão”
ao final deste. Esse tipo de situação jamais ocorrerá em Java, pois em Java o símbolo
} (fecha a chave) impede essa ocorrência.
Toda e qualquer instrução tem uma sintaxe, ou seja, uma forma exata como
deverá ser escrita. Vamos, por assim dizer, “definir” como se descreve as sintaxes,
usando para isso a instrução “Se”.
se <condicao> entao
<instrucao>
[ senao
<instrucao> ]
fim-se
2.1.3 Exemplos
Resolução:
Resolução:
2.1.4 EXERCÍCIOS
a) Dados dois números, por hipótese distintos entre si, imprima o maior deles.
Vamos considerar termos duas variáveis “a” e “b”, mas que em vez de valores,
tenham conteúdos booleanos, ou seja, assumem apenas situação de verdadeiro ou
falso. Podemos fazer uma analogia com um trem, que tem a frente um desvio. Uma
baliza (ou flag, se usarmos seu sinônimo em inglês) vai definir o destino desse
hipotético trem.
Supondo que nosso trem esteja partindo de Paris, mas num entroncamento é
decidido se ele irá para Roma ou para Berlim. Se esse entroncamento for uma
variável, “a” por exemplo, podemos definir que sempre que “a” for Verdade, então o
trem irá para Roma. Em caso contrário, irá para Berlim.
Todavia, podemos inserir novas variáveis. Por exemplo, uma variável “b” que
quando o trem não for para Roma, permita decidir se seu destino será Berlim ou
Praga. E assim sucessivamente.
Além disso, podemos incluir as palavras “E”, para indicar que uma condição
somente estará satisfeita se duas premissas forem simultaneamente verdadeiras ou
“OU” que indica que uma condição estará satisfeita, quando ao menos uma das
condições for verdadeira.
Voltando ao nosso hipotético trem, poderíamos dizer que ele irá para Roma se
“a” E “b” forem simultaneamente verdadeiros. Quando um dos dois for falso,
poderíamos estabelecer que se “a” for falso E “b” verdadeiro, então vamos para
Berlim. Já se “a” for falso E “b” verdadeiro, então vamos para Praga. Teríamos agora
a possibilidade de incluir um novo destino a nosso hipotético trem: Bratislava. Esse
seria o destino, na hipótese de “a” E “b” serem ambas falsas, simultaneamente.
O mesmo raciocínio se aplica a palavra “OU”. Todavia, seu uso é bem distinto.
Vamos imaginar que um vendedor seja recompensado com um bônus, quando tiver
feito mais de 50 visitas no mês ou quando tiver vendido além da meta. Se
considerarmos “a” uma variável booleana que tenha como conteúdo “Verdade” se o
vendedor fez mais de 50 visitas ou “Falso” quando tiver feito 50 ou menos visitas e “b”
de forma análoga, mas relativa a meta comercial, teríamos:
Se “a” verdade e “b” falso (visitou mais de 50, mas não atingiu a meta) então
bônus
Se “a” falso e “b” verdade (visitou 50 ou menos, mas atingiu a meta) então
bônus
Se “a” e “b” verdadeiros (visitou mais de 50 e atingiu a meta) então bônus
Se “a” e “b” falsos (nem visitou mais de 50 e também não atingiu a meta)
então sem bônus
Ou seja, somente numa condição nosso vendedor não receberá seu bônus.
A instrução SE pode ser usada de forma simples, como fizemos nos algoritmos
anteriores, mas também pode analisar expressões mais complexas, como veremos
no nosso próximo exemplo.
Resoluções
Como descobrir se um número é par ou ímpar? Bem, basta dividi-lo por dois:
Se a divisão for exata, ou seja, não deixar resto, o número é par, caso contrário, ele é
ímpar. Relembrando, o símbolo “%” (porcentual) é utilizado para realizar divisões e
retornar o resto da mesma.
2.2.3 SE encadeados
Resolução
Nosso algoritmo agora precisa resolver um problema que admite três saídas
distintas e testes que permitam identificar qual número é par. Podemos ter, inclusive,
como resposta a indicação de que o “primeiro é par” e o “segundo é par”. Notamos
que a variável “c” funciona como uma baliza, ou seja, ela indica se o fluxo do programa
passou num certo trecho. Assim, toda vez que alguma mensagem for apresentada,
“c” passa a valer 1 (um). Como “c” inicialmente vale 0 (zero), ora, se ao fim da
execução “c” continuar valendo zero, simplesmente saberemos que não houve
nenhuma mensagem apresentada até aquele momento, isto é, “a” e “b” são ímpares.
Vamos ficar atentos ao que é solicitado pelo enunciado, pois qualquer que seja
a hipótese indicada, testar sua veracidade sempre significará má compreensão do que
é pedido.
Repare que, se “a” era maior que “b”, mas não que “c”, então “c” é o maior dos
três!
Na hipótese de “a” não ser maior que “b”, resta apenas testar se “b” é maior
que “c”. Analogamente ao que ocorreu no teste anterior, se “b” também for maior que
“c”, então “b” será o maior dos três, caso contrário, o maior será “c”.
Resolução
Notemos que faremos apenas dois testes, qualquer que seja o número maior,
mesmo que tenhamos três estruturas de tomada de decisão. Isso ocorre porque o
bloco SE (ou bloco “verdadeiro”) e o SENÃO (ou bloco “falso”) nunca serão
executados juntos, irão sempre se alternar. Ao colocar uma estrutura de tomada de
decisão em cada bloco, aninhando-as, se a condição do primeiro teste for verdadeira,
nunca passaremos pelo SE que compara “b” com “c” e vice-versa. Trata-se de um
algoritmo muito interessante, que usa apenas três variáveis e sempre faz no
máximo duas comparações.
1) a > b > c
2) a > c > b
3) b > a > c
4) b > c > a
5) c > a > b
6) c > b > a
Resolução
Trata-se de um algoritmo muito ruim, que usa apenas três variáveis e sempre
faz três comparações por expressão. Como conta com seis expressões comparativas,
acaba executando, em qualquer situação, dezoito comparações.
Por não estarem aninhadas, mesmo que “tenhamos sorte” e o maior número
seja descoberto logo na primeira estrutura condicional, ainda sim, as outras cinco
condicionais serão testadas. Péssimo, não é?
1) a>b e a>c
2) b>a e b>c
3) c>a e c>b
Resolução
Nossa terceira estratégia, embora seja muito melhor que a segunda, ainda é
bastante inferior a primeira.
Vale notar que como nas demais, também se utiliza de três variáveis. Conta
com três expressões comparativas, cada uma delas com três comparações, portanto
executa sempre nove comparações, mesmo que o maior número seja
descoberto precocemente
Resolução
Desta feita, temos, na pior das situações, apenas quatro comparações. Estas
ocorrem quando “a” não é o maior, situação em que apenas três comparações seriam
executadas. Novamente temos apenas três variáveis sendo usadas.
Resolução
Para tanto, será necessária uma quarta variável (“d”) que servirá como variável
auxiliar ou de transporte, já que as variáveis trocarão seus valores.
Resolução
Todo algoritmo pode ser vertido para uma linguagem de programação e nela
ser executado, de forma a obtermos os resultados desejados através de seu
processamento. Todavia, não precisamos de linguagens para saber se nosso
raciocínio está correto. Podemos simular nossos algoritmos.
Vamos agora simular uma dessas versões, com a qual poderemos comparar o
desempenho de cada uma das soluções.
Exercício: simular, com os mesmos números, cada uma das demais soluções
apresentadas para o problema maior de 3.
Elabore algoritmo que dados três números inteiros, informe quantos deles
são ímpares:
Esse problema admite duas estratégias distintas para sua solução. A primeira
delas, bastante simples, chega a uma solução comum: contá-los conforme são
identificados. A segunda, aproveitando-se das características dos números inteiros,
chega a uma solução muito mais elegante e sofisticada. Vejamos o porquê disso.
São feitas três comparações antes de realizarmos cada uma das somas. Mas
pensando bem, será que isso é realmente necessário?
Vamos então observar como fica nosso algoritmo, se observarmos que se a cor
não for nem verde, nem vermelha, só poderá ser amarela.
2.5.3 Exercícios
a) Dados dois números inteiros e distintos entre si, imprima “Ambos Pares”,
“Ambos Ímpares” ou “Demais Casos”, conforme a situação
Algoritmo "Pares"
Var
numero_1: real;
numero_2: real;
teste1 : logico;
teste2 : logico;
Inicio
leia(numero_1)
leia(numero_2)
SE teste1 ENTÃO
SENAO
SE teste2 ENTÃO
SENAO
FIMSE
FIMSE
Fimalgoritmo
Algoritmo "Subtracao_distintos"
Var
numero_1: real;
numero_2: real;
calculo: real;
Inicio
leia(numero_1)
leia(numero_2)
SENAO
FIMSE
FIMSE
Fimalgoritmo
Algoritmo "Subtracao_idênticos"
Var
numero_1: real;
numero_2: real;
calculo: real;
Inicio
leia(numero_1)
leia(numero_2)
SENAO
SENÃO
FIMSE
FIMSE
Fimalgoritmo
Elabore um algoritmo que receba uma variável qualquer inteira. Se esta tiver
o valor 1 (um), imprima “vermelho”, se tiver o valor 2 (dois) imprima “verde”
e em outras situações, imprima “amarelo”.
escolha <variável>:
<instrução 1>;
fim-caso
<instrução 2>;
fim-caso
<instrução n>;
fim-caso
outrocaso:
<instrução>;
fim-caso ]
fim-escolha
É fácil observar que a estrutura lógica equivale e pode ser substituída por uma
série de decisões do tipo “se então senão se...”, mas a complexidade ao menos de
leitura causada pelos inúmeros aninhamentos, aumenta exponencialmente quando
usamos essa estratégia.
O exemplo, embora muito simples, retrata uma situação bastante usual em que
um conjunto de opções é apresentado numa espécie de menu, que resulta no seguinte
código:
Uma função muito simples é a que recebe dois números e retorna sua soma.
Primeiramente, vamos fazer esse “programa” da forma mais trivial, sem usarmos uma
função:
Figura 2.31 – Exemplo de programa que soma dois números fornecidos pelo usuário.
Fonte: Elaborado pelo autor (2015)
Figura 2.32 – Exemplo de programa que soma dois números fornecidos pelo usuário com
uma função.
Fonte: Elaborado pelo autor (2015)
Pudemos notar que a soma foi realizada numa rotina à parte que, de posse dos
valores digitados, fez o cálculo e o retornou o valor e seu processamento ao programa
chamador. Portanto, a função recebe dois parâmetros de entrada de informação, os
utiliza no cálculo e retorna um valor inteiro como saída, ao programa que o chamou.
Observando a figura anterior, notamos que “A” e “B” são variáveis globais, ou
seja, são vistas por qualquer subalgoritmo (função/procedimento).
Deve ser observado que parâmetros podem ser passados por valor ou por
referência.
No exemplo a seguir, embora seja solicitada uma troca, esta ocorre apenas nas
variáveis “n1” e “n2”, mas não entre “a” e “b”, as variáveis que foram usadas para
passagem dos parâmetros.
Algoritmo "TentandoComValores";
Var
a,b: Inteiro
Var
z: Inteiro
inicio
z<-x
x<-y
y<-z
fimprocedimento
Inicio
leia(a)
leia(b)
trocarComValores(a,b)
Escreval(a)
Escreval(b)
Fimalgoritmo
Algoritmo "TentandoComReferencia";
Var
a,b: Inteiro
Inicio
leia(a)
leia(b)
trocarComReferencia(a,b)
Escreval(a)
Escreval(b)
Fimalgoritmo
Algoritmo "Exercicio_Fixação_A"
Var
numero_1: real;
numero_2: real;
teste_1: logico;
teste_2: logico;
Inicio
leia(numero_1)
leia(numero_2)
SE teste_1 ENTÃO
SENAO
SE teste_2 ENTÃO
escreva ("Laranja")
SENÃO
escreva ("Roxo")
FIMSE
FIMSE
Fimalgoritmo
algoritmo "Exercicio_Fixação_b"
Var
num1: real;
num2: real;
num3: real;
menor: real;
soma: real;
Inicio
menor := 99999999999999999999
soma := 0
leia (num1)
leia (num2)
leia (num3)
menor := num1
FIMSE
menor := num2
FIMSE
menor := num3
FIMSE
FIMSE
FIMSE
FIMSE
fimalgoritmo
algoritmo "Exercicio_Fixação_c"
var
a: inteiro;
b: inteiro;
c: inteiro;
inicio
leia(a,b,c)
escreva(c,b,a)
senao
se (b>=a)e(b>c)e(a>=c)ENTÃO
escreva(c,a,
senao
se(b>a)e(b>=c)e(a<=c)ENTÃO
escreva(a,c,
senao
se (b>a)e(b<=c)ENTÃO
escreva(a,b,c)
senao
se(b<a)e(a<c)ENTÃO
escreva(b,a,c)
senao
se(b<c)e(c<=a)ENTÃO
escreva(b,c,a)
senao
escreval(a,b,c)
fimse
fimse
fimse
fimse
fimse
fimse
fimalgoritmo
Elabore um algoritmo que solicite ao usuário a idade e o nível de risco (“B” para
“baixo risco”, “M” para “médio risco” e “A” para “alto risco”) e a partir deles calcule a
categoria do seguro, exibindo o número de 1 a 9 na tela.
algoritmo "Exercicio_Fixação_d"
var
idade: inteiro;
risco: caractere;
inicio
leia(idade)
leia(risco)
escolha (risco)
caso "B"
caso "M"
caso "A"
fimescolha
senao
escolha (risco)
caso "B"
caso "M"
caso "A"
fimescolha
senao
escolha (risco)
caso "B"
caso "M"
caso "A"
fimescolha
senao
escolha (risco)
caso "B"
caso "M"
caso "A"
fimescolha
senao
escolha (risco)
caso "B"
caso "M"
caso "A"
fimescolha
fimse
fimse
fimse
fimse
fimse
fimalgoritmo
algoritmo "Exercicio_Fixação_e"
var
numero_1: inteiro;
numero_2: inteiro;
inicio
leia(numero_1)
leia(numero_2)
escreval ("Pares")
senao
escreval ("Impares")
senao
escreval ("Outro")
fimse
fimse
fimalgoritmo
Var
num1: real;
num2: real;
num3: real;
menor: real;
maior: real;
subtracao: real;
Inicio
leia (num1)
leia (num2)
leia (num3)
SE (num1 > num2) e (num1 > num3) e (num2 > num3) ENTÃO
menor := num3
maior := num1
SENÃO
SE (num1 > num2) e (num1 > num3) e (num3 > num2) ENTÃO
menor := num2
maior := num1
SENÃO
SE (num2 > num1) e (num2 > num3) e (num1 > num3) ENTÃO
menor := num3
maior := num2
SENÃO
SE (num2 > num1) e (num2 > num3) e (num3 > num1) ENTÃO
menor := num1
maior := num2
SENÃO
SE (num3 > num1) e (num3 > num2) e (num1 > num2) ENTÃO
menor := num2
maior := num3
SENÃO
SE (num3 > num1) e (num3 > num2) e (num2 > num1) ENTÃO
menor := num1
maior := num3
FIMSE
FIMSE
FIMSE
FIMSE
FIMSE
FIMSE
fimalgoritmo
algoritmo "Exercicio_Fixação_g"
Var
num1: real;
num2: real;
num3: real;
menor: real;
maior: real;
subtracao: real;
iguais: logico;
Inicio
leia (num1)
leia (num2)
leia (num3)
SE (num1 > num2) e (num1 > num3) e (num2 > num3) ENTÃO
menor := num3
maior := num1
SENÃO
SE (num1 > num2) e (num1 > num3) e (num3 > num2) ENTÃO
menor := num2
maior := num1
SENÃO
SE (num2 > num1) e (num2 > num3) e (num1 > num3) ENTÃO
menor := num3
maior := num2
SENÃO
SE (num2 > num1) e (num2 > num3) e (num3 > num1) ENTÃO
menor := num1
maior := num2
SENÃO
SE (num3 > num1) e (num3 > num2) e (num1 > num2) ENTÃO
menor := num2
maior := num3
SENÃO
SE (num3 > num1) e (num3 > num2) e (num2 > num1) ENTÃO
menor := num1
maior := num3
SENÃO
iguais := VERDADEIRO
FIMSE
FIMSE
FIMSE
FIMSE
FIMSE
FIMSE
SE (iguais) ENTÃO
SENÃO
FIMSE
fimalgoritmo
algoritmo "Exercicio_Fixação_h"
var
idade: inteiro;
valor_base: real;
valor_final: real;
valor_final1: real;
genero: caractere;
inicio
escolha (genero)
caso "F"
valor_final := valor_base * 1 * (8/10)
caso "M"
valor_final := valor_base * 1
fimescolha
senao
escolha (genero)
caso "M"
valor_final := valor_base * 2
caso "F"
valor_final := valor_base * 2 * (8/10)
fimescolha
senao
escolha (genero)
caso "M"
valor_final := valor_base * 3
caso "F"
valor_final := valor_base * 3 * (8/10)
fimescolha
senao
escolha (genero)
caso "M"
valor_final := valor_base * 4
caso "F"
valor_final := valor_base * 4 * (8/10)
fimescolha
senao
escolha (genero)
caso "M"
valor_final := valor_base * 7
caso "F"
valor_final := valor_base * 7 * (8/10)
fimescolha
fimse
fimse
fimse
fimse
fimse
fimalgoritmo
algoritmo "Exercicio_Fixação_i"
var
numero: inteiro;
inicio
senao
senao
se (numero = 0) ENTÃO
senao
fimse
fimse
fimse
fimalgoritmo
algoritmo "Exercicio_Fixação_j"
var
numero_1: inteiro;
numero_2: inteiro;
numero_3: inteiro;
inicio
senao
senao
senao
senao
fimse
fimse
fimse
fimse
fimalgoritmo
k) Certo país usa para cartas simples selos de 3 e de 5 centavos. A taxa mínima
existente (peso da carta) é de 8 centavos. Deseja-se determinar o menor número de
selos de 3 e 5 centavos combinados que completem uma taxa dada. Elabore algoritmo
que faça esse cálculo para as caixas.
Exemplos:
8=3+5 11 = 3 + 8 14 = 3 + 11
9=3*3 12 = 3 + 9 15 = 3 + 12
10 = 5 * 2 13 = 3 + 10 16 = 3 + 13
algoritmo "Exercicio_Fixação_k"
var
taxa: inteiro;
tres: inteiro;
cinco: inteiro;
inicio
leia(taxa)
cinco := INT(taxa / 5)
SENÃO
cinco := INT((taxa - 6) / 5)
tres := 2
SENÃO
tres := 4
SENÃO
cinco := INT((taxa - 3) / 5)
tres := 1
SENÃO
cinco := INT((taxa - 9) / 5)
tres := 3
fimse
fimse
fimse
fimse
fimse
fimalgoritmo
REFERÊNCIAS
GANE, Chris e SARSON, Trish. Análise Estruturada de Sistemas. São Paulo: LTC,
1983.
SCHILDT, Herbert. Linguagem C - Guia Prático. São Paulo: McGraw Hill, 1989.
WOOD, Steve. Turbo Pascal – Guia do Usuário. São Paulo: McGraw Hill, 1987.