CAPÍTULO 1
INTRODUÇÃO À LÓGICA
Fabio Augusto Oliveira
Guilherme da Cunha Fonseca
FEPI – Centro Universitário de Itajubá
Curso de Engenharia de Produção
1 INTRODUÇÃO
Um programa de computador é essencialmente composto por cálculos e decisões
lógicas. Com os cálculos já estamos acostumados: são contas de soma, subtração,
multiplicação, dentre tantas outras. Mas e a parte das decisões lógicas?
As decisões lógicas são aquelas que coordenam a execução dos cálculos, para que,
em conjunto, eles produzam o resultado para um problema maior. São as decisões
lógicas que definem se um cliente tem ou não desconto em sua compra, ou se um
aluno foi ou não aprovado em seu curso.
Dada a importância da lógica neste processo, pode-se dizer que programar um
computador é, em grande parte, um exercício de lógica.
Esta nota de aula apresentará o conceito de lógica e como usá-la para construir
algoritmos, isto é, coordenar a execução de cálculos para resolver um problema
maior.
2 O QUE É LÓGICA?
Ainda que não percebamos, a lógica está presente em nosso dia-a-dia. Quando o
professor diz ao aluno que ele precisa ter frequência de pelo menos 75% E média de
Programação Computacional – Notas de Aula – Capítulo 01 – 2
pelo menos 6,0 para ser aprovado, o aluno sabe que não adianta atender aos 75% de
frequência se não tiver média 6,0; o contrário também vale: de nada adianta ter
10,0 de média se a frequência for inferior a 75%.
Caso o professor tivesse dito que basta o aluno ter frequência acima de 75% OU
média de pelo menos 6,0 para ser aprovado, a história seria completamente
diferente, não é mesmo?
A diferença de interpretação destas duas colocações está, exatamente, na lógica
apresentada por elas. Repare nas pequenas partículas em negrito, E e OU. São elas
que fazem toda a diferença.
3 ALGORITMOS
Algoritmo é a forma organizada de expressar uma sequência de passos que visam
atingir
um
objetivo
definido.
Algoritmo
é
a
lógica
necessária
para
o
desenvolvimento de um programa.
Apesar do nome estranho, os algoritmos são muito comuns no nosso cotidiano, como
por exemplo, em uma receita de bolo. Nela estão escritos os ingredientes
necessários e a sequências de passos ou ações a serem cumpridos para que se
consiga fazer um determinado tipo de bolo.
Em
um
modo
geral,
um
algoritmo
segue
um
determinado
padrão
de
comportamento, com objetivo de alcançar a solução de um problema.
Padrão de comportamento: imagine a sequência de números: 1, 6, 11, 16, 21, 26,...,
para determinar qual será o sétimo elemento dessa série, necessitamos descobrir
qual é a sua regra de formação, isto é, qual é o seu padrão de comportamento.
Como a sequência segue certa constância, facilmente determinada, somos capazes
de determinar qual seria o sétimo termo ou outro termo qualquer.
Descrevemos então uma atividade bem cotidiana: trocar uma lâmpada.
Apesar de parecer óbvia demais, muitas vezes fazemos este tipo de atividade
inconscientemente, sem percebermos os pequenos detalhes.
Programação Computacional – Notas de Aula – Capítulo 01 – 3
Vejamos como seria descrevê-la passo a passo:
1. Pegar uma escada;
2. Posicionar a escada embaixo da lâmpada;
3. Buscar uma lâmpada nova;
4. Subir na escada;
5. Retirar a lâmpada velha;
6. Colocar a lâmpada nova.
Para se trocar a lâmpada, é seguida uma determinada sequência de ações,
representadas através desse algoritmo. Como isso pode ser seguido por qualquer
pessoa, estabelece-se aí um padrão de comportamento. A sequenciação tem por
objetivo reger o fluxo de execução, determinando qual ação vem a seguir.
O algoritmo anterior tem um objetivo bem específico: trocar uma lâmpada. E se a
lâmpada não estiver queimada? O algoritmo faz com ela seja trocada do mesmo
modo, não prevendo essa situação. Para solucionar este problema, podemos efetuar
um teste condicional, verificando se a lâmpada está ou não queimada:
1. Pegar uma escada;
2. Posicionar embaixo da lâmpada;
3. Buscar uma lâmpada nova;
4. Ligar o interruptor;
5. Se a lâmpada não acender, então:
1. Subir na escada;
2. Retirar a lâmpada velha;
3. Colocar a lâmpada nova.
Dessa forma, algumas ações estão ligadas à condição (lâmpada não acender). No
caso da lâmpada acender, as três linhas:
1. Subir na escada;
2. Retirar a lâmpada velha;
3. Colocar a lâmpada nova.
Programação Computacional – Notas de Aula – Capítulo 01 – 4
3.1 Fatores a serem levados em consideração na construção de
um algoritmo
3.1.1 Complexidade
Percebeu-se, na medida em que colocávamos situações novas no problema a ser
resolvido, ia aumentando a complexidade do algoritmo. Esse certamente é o maior
problema envolvido na construção de algoritmos. A complexidade pode ser vista
como um sinônimo de variedade (quantidade de situações diferentes que um
problema pode apresentar), as quais devem ser previstas na sua solução.
Já que conviver com a complexidade é um mal necessário, é saudável fazer o
possível para diminuí-la ao máximo, a fim de controlar o problema e encontrar sua
solução.
Deve-se diferenciar O QUE de COMO. Muitos programadores aumentam a
complexidade de um devido problema desnecessariamente. A forma errada de
interpretação de um problema pode levar a respostas irrelevantes à solução
almejada ou até mesmo a nenhuma solução, gerando algoritmos mais complexos do
que o necessário.
Exemplo: digamos que se pergunte a um leigo a respeito de um relógio:
1. Como é um relógio?
= É um instrumento com três ponteiros concêntricos.
2. Como a descrição não é relevante, poderíamos indagar: Um relógio com 2
ponteiros é possível?
= É... pode ser!
3. Poderíamos ainda indagar: E um relógio com apenas 1 ponteiro não poderia
ser uma possibilidade?
= Bem... Pode ser com 3, 2 ou 1 ponteiro.
4. E sem ponteiro pode?
Programação Computacional – Notas de Aula – Capítulo 01 – 5
= Ah!, Sim! Pode ser digital
5. Já a pergunta: “O que é um relógio?”, poderia resultar na resposta:
= É um instrumento cuja finalidade é marcar o decorrer do tempo.
Ou seja, algumas variáveis podem aumentar ou diminuir a complexidade de um
sistema quando forem bem ou mal utilizadas.
3.1.2 Legibilidade
Mede a capacidade de compreensão de um algoritmo por qualquer
observador (que não o construiu), ou seja, a clareza com que sua lógica está
exposta. Quanto mais legível for um algoritmo, menor será sua complexidade.
3.1.3 Portabilidade
Devido a quantidade enorme de linguagens de programação existentes, não será
adotada nenhuma linguagem específica para trabalhar os algoritmos (Ex.: C,
pascal, Java etc.). Isso porque a solução do problema fica ligada a características e
recursos da linguagem na qual ela foi concebida.
Utilizaremos um pseudocódigo ou portugol (linguagem fictícia) que visa a permitir
a representação dos algoritmos através da língua portuguesa (português
estruturado). Esses algoritmos poderão ser convertidos facilmente para qualquer
linguagem de programação usual (C, C++, pascal, Java etc.).
3.1.4 Técnica de resolução por método cartesiano
A famosa frase de Descartes “Dividir para conquistar” é muito importante dentro
da programação. É um método que ataca um problema grande, de difícil solução,
dividindo-o em problemas menores, de solução mais fácil. Se necessário, pode-se
dividir novamente as partes não compreendidas. Esse método pode ser
esquematizado em passos:
1. Dividir o problema em partes;
2. Analisar a divisão e garantir a coerência entre as partes;
Programação Computacional – Notas de Aula – Capítulo 01 – 6
3. Reaplicar o método, se necessário;
ou
4. Planejamento reverso: Consiste em, a partir do resultado final,
determinar quais são os componentes básicos. Ou seja, a partir da saída
desejada, devemos poder determinar, reversamente, quais são os
componentes da entrada de dados necessários.
3.2 Método para construir um algoritmo
Utilizando os conceitos já desenvolvidos, esquematizaremos um método para
construir um algoritmo logicamente correto:
3.2.1 Ler atentamente o enunciado
Deve-se reler o enunciado de um exercício quantas vezes forem necessárias, até
compreendê-lo completamente. A maior parte da resolução de um exercício consiste
na compreensão completa do enunciado.
3.2.2 Retirar a relação das entradas de dados do enunciado
Através do enunciado, descobrimos quais são os dados que devem ser fornecidos ao
programa, via teclado, a partir dos quais são desenvolvidos os cálculos.
Obs.: Pode haver algum algoritmo que não necessite da entrada de dados (pouco
comum).
3.2.3 Retirar do enunciado, a relação das saídas de informação
Através do enunciado podemos descobrir quais são as informações que devem ser
mostradas para compor o resultado final, objetivo do algoritmo.
3.2.4 Determinar o que deve ser feito para transformar as entradas nas saídas
especificadas
Nessa fase é que teremos a construção do Algoritmo propriamente dito. Devemos
determinar qual sequência de passos ou ações é capaz de transformar um conjunto
de dados nas informações de resultado. Para isso, utilizamos os fatores descritos
Programação Computacional – Notas de Aula – Capítulo 01 – 7
anteriormente, tais como legibilidade, portabilidade, método cartesiano e
planejamento reverso, e finalmente podemos construir o algoritmo.
3.3 Exercício de Fixação
1. Elabore um algoritmo que mova 3 discos de uma torre de Hanói, que
consiste em 3 hastes (A-B-C), uma das quais serve de suporte para os três
discos de tamanhos diferentes (1-2-3), os menores sobre os maiores. Siga as
seguintes regras:
i.
Deve-se mover um disco de cada vez para qualquer haste;
ii.
Nunca deve ser colocado um disco maior sobre um menor.
iii.
O objetivo é transferir os três discos da haste A para haste C.
•
Solução: 7 movimentos
1. Mova disco 1 da haste A para haste C
2. Mova disco 2 da haste A para haste B
3. Mova disco 1 da haste C para haste B
4. Mova disco 3 da haste A para haste C
5. Mova disco 1 da haste B para haste A
6. Mova disco 2 da haste B para haste C
7. Mova disco 1 da haste A para haste C
•
Explicações:
Alguns pontos são necessários ressalta quanto a solução deste problema da
torre de Hanói:
 Existe uma formula matemática para descobrirmos o número ideal de
movimentos que devemos realizar. Esta formula é representada por:
T(n) = 2n − 1, na qual T(n) representa o menor número de movimentos
em função de n que representa o número de discos do problema.
Programação Computacional – Notas de Aula – Capítulo 01 – 8
 Outro ponto a se observado, é para qual haste devemos movimentar o
primeiro disco. Este primeiro movimento e muito importante, pois se ele
for feito para a haste errada, resultará em um numero maior de
movimentos. A regra é a seguinte, se possuirmos um número impar de
discos, deve-se movimentar o primeiro disco para a haste onde se deseja
ao final manter todos os discos. No exercício acima o primeiro movimento
deverá ser, portanto para a haste C, caso o disco seja movimentado para
a haste B tem-se dois ou mais movimentos desnecessários, conforme
mostrado abaixo:
1.
2.
3.
4.
5.
6.
7.
8.
9.
9 Movimentos
Mova disco 1 da haste A para haste B
Mova disco 2 da haste A para haste C
Mova disco 1 da haste B para haste A
Mova disco 2 da haste C para haste B
Mova disco 1 da haste A para haste B
Mova disco 3 da haste A para haste C
Mova disco 1 da haste B para haste A
Mova disco 2 da haste B para haste C
Mova disco 1 da haste A para haste C
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
11 Movimentos
Mova disco 1 da haste A para haste B
Mova disco 2 da haste A para haste C
Mova disco 1 da haste B para haste C
Mova disco 3 da haste A para haste B
Mova disco 1 da haste C para haste B
Mova disco 2 da haste C para haste A
Mova disco 1 da haste B para haste A
Mova disco 3 da haste B para haste C
Mova disco 1 da haste A para haste B
Mova disco 2 da haste A para haste C
Mova disco 1 da haste B para haste C
 Com dois discos observe solução abaixo, que comprovará a explicação
dada acima para o primeiro movimento quanto temos um numero par de
discos e quando temos um numero impar de discos:
1.
2.
3.
3 Movimentos
Mova disco 1 da haste A para haste B
Mova disco 2 da haste A para haste C
Mova disco 1 da haste B para haste C
1.
2.
3.
4.
5.
5 Movimentos
Mova disco 1 da haste A para haste C
Mova disco 2 da haste A para haste B
Mova disco 1 da haste C para haste A
Mova disco 2 da haste B para haste C
Mova disco 1 da haste A para haste C
 Outro ponto importante a ser observado e que sempre o número de
movimentos deverá ser impar, caso a solução seja um número par de
trocas estará incorreta.
Programação Computacional – Notas de Aula – Capítulo 01 – 9
2. Um homem viajava transportando junto a si um balde de leite, um cão e um
gato. Em certo momento da viagem precisou atravessar um rio. Ali
encontrava a sua disposição um barco que possui capacidade de transporte
apenas dele mesmo e mais uma de suas três cargas. O que o homem deve
fazer para conseguir atravessar o rio sem perder suas cargas?
Nota: O gato bebe o leite;
O cão come o gato;
Informações: homem, cão, gato, leite e barco.
Ação: transportar homem mais carga com segurança.
Resultado: Atravessar as cargas para a outra margem do rio.
•
Solução:
1. Atravessar o homem e o gato;
2. Voltar o homem;
3. Atravessar o homem e o leite;
4. Voltar o homem e o gato;
5. Atravessar o homem e o cão;
6. Voltar o homem;
7. Atravessar o homem e o gato.
3. Três Jesuítas e três canibais precisam atravessar um rio, para tal, dispõe de
um barco com capacidade para duas pessoas. Por medidas de segurança não
se permite que em alguma margem a quantidade de jesuítas seja inferior a
de canibais. Qual a sequência de passos que permitirá atravessar com os
jesuítas e canibais com segurança?
Informações: Três jesuítas, Três canibais, Um barco com capacidade
para duas pessoas.
Ação: Atravessar para a outra margem do rio.
Resultado: Chegar com segurança.
•
Solução:
1. Atravessar um Jesuíta e um Canibal
2. Voltar um Canibal
3. Atravessar dois Canibais
4. Voltar um Canibal
5. Atravessar um Jesuíta e um Canibal
6. Voltar um Canibal
7. Atravessar dois Canibais
8. Voltar um Canibal
9. Atravessar um Jesuíta e um Canibal.
Programação Computacional – Notas de Aula – Capítulo 01 – 10
4 PSEUDOCÓDIGOS E FLUXOGRAMAS
4.1 Pseudocódigos
O pseudocódigo é um código simplório, ou seja, não é um código real, mas um código
imaginário que lembra o código de programação.
O pseudocódigo é muito utilizado para apresentar a lógica algorítmica de forma
mais simples, sem ter que se preocupar muito com o aspecto técnico das linguagens
reais.
O pseudocódigo não segue um padrão definido, portanto, qualquer um pode
escrever seu pseudocódigo da forma que bem entender desde que ele transmita a
ideia central da lógica da programação. Por exemplo, abaixo estão dois
pseudocódigos que descrevem o mesmo algoritmo:
Exemplo 1:
INICIO
entrada de dado : grava em VAR1
verificar VAR1 : letra ?
verdade : imprimir dado -> "Você digitou uma letra"
falso : imprimir dado -> "Você digitou um número"
FIM
Exemplo 2:
INICIO: procedimento
VARIÁVEIS var1
var1 <- entrada de dados:TECLADO
se (var1 É letra) então
imprimir dado:MONITOR -> "Você digitou uma letra"
caso contrário
imprimir dado:MONITOR -> "Você digitou um número"
FIM: procedimento
4.2 Fluxogramas
Fluxogramas têm o mesmo objetivo dos pseudocódigos, a única diferença é que os
fluxogramas são representações gráficas.
Programação Computacional – Notas de Aula – Capítulo 01 – 11
A vantagem principal dos fluxogramas é que, diferentemente dos pseudocódigos,
eles são padronizados. Ou seja, cada símbolo representa uma ação específica e
sempre representará.
Um fluxograma usa linhas para ligar seus elementos, criando assim, um caminho
que deve ser seguido.
Abaixo está uma tabela com as representações do fluxograma e o que são.
Inicio e Fim
Sentença e Comandos
Conectores de fluxo
Estrutura de Seleção
Estrutura de Repetição
Processo Alternativo
Programação Computacional – Notas de Aula – Capítulo 01 – 12
Programação Computacional – Notas de Aula – Capítulo 01 – 13
Fluxogramas
Fluxograma para testar A<B<C;
Programação Computacional – Notas de Aula – Capítulo 01 – 14
5 EXERCÍCIOS PROPOSTOS:
1. Dada a série de números: 1, 1, 2, 3, 5, 8, 13, qual é o próximo?
2. Um pai preocupado com a saúde de seus filhos quer que eles comam maçãs, mas
não sabe fazer a distribuição. Se der 5 maçãs para cada filho, vão lhe sobrar
quatro, se der 6, vai faltar uma. Quantos filhos e quantas maçãs ele tem?
3. Daniela é mais jovem do que Adriano. Carlos é mais velho do que Daniela. Qual
dessas conclusões é verdadeira?
a. Adriano é mais velho do que Carlos.
b. Carlos é mais velho do que Adriano.
c. Daniela é a mais jovem dos três.
4. Distribua os números de 1 a 9 nos círculos abaixo, de modo que a soma das
linhas seja sempre 10.
5. Em uma folha de papel traçam-se duas retas, formando um ângulo de 15°. Ao
utilizar uma lente que aumenta três vezes, quantos graus passará a ter o
ângulo?
6. Oito pessoas de uma só família estão sentadas em volta de uma mesa redonda.
Seu Daniel é o chefe da família, é casado com dona Marina, ótima cozinheira,
principalmente aos domingos, quando toda a família vem almoçar. Eles têm 3
filhos: Claudinho, que é casado com Doroti; Luísa, que é solteira e estuda nos
Estados Unidos; e Júlio, que é viúvo. A filha de Claudinho e Doroti chama-se
Sônia e sempre se senta entre os dois. Os filhos de Júlio chamam-se Pedro e
Paulo, sempre estão brigando, e a avó não permite que se sentem juntos. Júlio
Programação Computacional – Notas de Aula – Capítulo 01 – 15
sempre coloca os cotovelos na mesa e isso irrita Doroti, que sempre fica longe
dele. Júlio prefere sentar-se no lado esquerdo do pai. Dona Marina tem um
carinho especial pelo neto Pedro e está sentada ao lado dele, enquanto conversa
animadamente com sua nora, que está à sua esquerda. Paulo sempre chega
depois que o almoço foi servido e nunca fica contente com o lugar que sobrou
para ele. Em que lugares estão sentadas todas as pessoas em volta da mesa?
7. Descreva a sequência de passos necessária para:
a. Fritar um ovo
b. Trocar um pneu furado
c. Colocar um carro em movimento
d. Atravessar a rua
e. Fazer as malas
f.
Fazer uma prova
g. Jogar o jogo da forca
h. Jogar o jogo da velha
Download

CAPÍTULO 1 INTRODUÇÃO À LÓGICA