Lógica de Programação I - UEG

Propaganda
Lógica de Programação I
Gilson de Souza Carvalho
[email protected]
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
1
Lógica de Programação I
Comandos de Repetição
Comandos de repetição
comandos de condição
combinados
com
A utilização de comandos de repetição combinados
com comandos de condição permite resolver
problemas bem mais complexos que os vistos até
agora. Na realidade, o ferramental já apresentado é a
base para toda a sequência de algoritmos, e sua
compreensão é absolutamente fundamental para o
desenvolvimento de algoritmos mais sofisticados.
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
2
Lógica de Programação I
Comandos de Repetição
Os comandos de condição podem fazer parte de
blocos pertencentes a comandos de repetição e
vice-versa. Ou seja, estruturas como as descritas a
seguir podem ocorrer intercaladas quantas vezes
forem necessárias.
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
3
Lógica de Programação I
Comandos de Repetição
...
if <valor boolean> {
...
while <valor boolean> {
...
}
...
}
//} do bloco if
...
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
4
Lógica de Programação I
Comandos de Repetição
...
else {
...
while <valor boolean> {
...
if <valor boolean> {
...
}
else {
...
}
}
}
<continuação do algoritmo>
//} do bloco while
//} do bloco else}
}
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
5
Lógica de Programação I
Comandos de Repetição
Na estrutura anterior temos comandos de decisão
aninhados a comandos de repetição e vice-versa.
Esse tipo de estrutura é extremamente útil para
resolver problemas em diversas situações. Vejamos
a seguir alguns exemplos.
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
6
Lógica de Programação I
Comandos de Repetição
Calcular a soma dos números ímpares de um intervalo
Faça um algoritmo que calcule a soma de todos os
números ímpares dentro de uma faixa de valores
determinada pelo usuário.
Um numero é ímpar quando sua divisão por 2 não é
exata, ou seja, o mod(%) resultante da divisão inteira
do numero por 2 tem valor 1.Vejamos como fica o
código:
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
7
Lógica de Programação I
Comandos de Repetição
if ((numero % 2) != 0)
<código para numero impar>
else
<código para numero par>
Como o algoritmo solicita a soma dos valores ímpares dentro
de uma faixa, teremos que fazer o acúmulo do resultado
apenas quando a condição ímpar for atendida. Essa condição
será testada para todos os números dentro da faixa, por meio
de um laço.
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
8
Lógica de Programação I
Comandos de Repetição
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main()
{
setlocale(LC_ALL,"portuguese");
unsigned short int n_inf, n_sup, s_impar;
n_inf = n_sup = s_impar = 0;
printf("Informe 2 numeros referente ao intervalo: \n");
scanf("%d %d", &n_inf, &n_sup);
...
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
9
Lógica de Programação I
Comandos de Repetição
...
while (n_inf <= n_sup)
{
if ((n_inf % 2) != 0)
s_impar += n_inf;
n_inf++;
}
printf("Soma dos Impares: %d\n", s_impar);
return 0;
}
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
10
Lógica de Programação I
Comandos de Repetição
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
11
Lógica de Programação I
Comandos de Repetição
1. do o teste de mesa com intervalo definido entre 1 e
5.
2. Adapte o algoritmo Soma_Ímpares, para obrigar o
usuário a entrar com um valor para o limite inferior
menor que o valor definido para o limite superior.
Para isto, faça um laço que garanta a entrada de um
intervalo válido (inferior > superior).
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
12
Lógica de Programação I
Comandos de Repetição
Determinar if um numero é primo
Faça um algoritmo que escaneie um numero inteiro positivo e
determine if este é primo ou não.
Por definição, um numero é primo quando é divisível somente
por si próprio e por 1, Portanto, para determinar if um
numero é primo, temos de definir por quais números é
divisível. A aproximação mais simples, e que podemos dizer
ser uma aproximação de 'força bruta', poderia ser testar a
divisibilidade do numero avaliado por todos os números
menores que ele, Vejamos a implementação deste algoritmo.
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
13
Lógica de Programação I
Comandos de Repetição
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <stdbool.h>
int main()
{
setlocale(LC_ALL,"portuguese");
unsigned short int n1 = 0, divisor = 0;
bool booleano = false;
printf("Informe o numero a ser testado: ");
scanf("%d", &n1);
...
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
14
Lógica de Programação I
Comandos de Repetição
...
divisor = n1 - 1;
while (divisor > 1 && booleano == false)
{
if (n1 % divisor == 0)
booleano = true;
else
divisor = divisor - 1;
}
if (booleano == false)
printf("Número é primo!");
else
printf("Número não é primo!");
return 0;
}
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
15
Lógica de Programação I
Comandos de Repetição
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
16
Lógica de Programação I
Comandos de Repetição
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main()
{
setlocale(LC_ALL,"portuguese");
unsigned short int n1 = 0, divisor = 0;
printf("Informe o numero a ser testado: ");
scanf("%d", &n1);
...
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
17
Lógica de Programação I
Comandos de Repetição
...
divisor = n1 - 1;
while (divisor > 1)
{
if (n1 % divisor == 0) {
printf("Número não é primo! \n");
exit(0);
}
else
divisor -= 1;
}
printf("Número é primo! \n");
return 0;
}
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
18
Lógica de Programação I
Comandos de Repetição
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
19
Lógica de Programação I
Comandos de Repetição
Apesar de o algoritmo Primo_Versão1 ser eficaz,
visto que resolve o problema para o qual foi
projetado, não if pode dizer que seja
propriamente eficiente. Basta que analisemos
com um pouco mais de profundidade que
perceberemos que várias otimizações podem
ser aplicadas ao raciocínio utilizado nesse
algoritmo. Vejamos:
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
20
Lógica de Programação I
Comandos de Repetição
*Números pares (com exceção do 2) não podem ser primos,
visto que são divisíveis por 2, if um numero não for divisível
por 2, não será divisível por nenhum outro numero par.
Portanto, com exceção do numero 2, só precisaremos testar
números ímpares.
**É mais fácil que um numero seja divisível por um numero
pequeno do que por um numero maior, Portanto, if iniciarmos
a procura do divisor de baixo para cima, ao invés de cima para
baixo, como foi implementado, teremos chance de encontrar
o numero muito antes.
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
21
Lógica de Programação I
Comandos de Repetição
***Nenhum numero pode ser divisível por outro
numero maior que a metade dele. Portanto, não
precisamos testar a divisibilidade dos numero na
faixa entre a metade e o próprio numero.
if levarmos em conta tais considerações, teremos
um algoritmo muito mais eficiente que o anterior,
pois executará muito menos instruções para
responder a mesma questão.
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
22
Lógica de Programação I
Comandos de Repetição
LP1_16
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
23
Lógica de Programação I
Comandos de Repetição
LP1_16
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
24
Lógica de Programação I
Comandos de Repetição
Um raciocínio mais sofisticado pode ainda nos dar uma otimização
final. Vejamos alguns exemplos para facilitar a compreensão deste
ponto:
• 15 é divisível pelos números 1,3,5 e 15(1*15,3*5, 5*3 e 15*1).
• 16 é divisível pelos números 1, 2, 4, 8 e 16 (1*16,2*8,4*4,8*2 e
16*1).
• 17 é divisível pelos números 1 e 17(1*17 e 17*1).
• 20 é divisível pelos números 1, 2, 4, 5, 10 e 20 (1*20,2*10,4*5,
5*4,10 *2 e 20*1).
• 25 é divisível pelo números 1, 5 e 25 (1*25,5*5 e 25*1).
• 36 é divisível pelo números 1, 2, 3,4,6,9, 12, 18 e 36 (1*36, 2*18,
3* 12,4*9, 6*6,9*4, 12*3, 18*2 e 36*1).
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
25
Lógica de Programação I
Comandos de Repetição
Os exemplos anteriores são para ilustrar a seguinte
propriedade da divisibilidade de um numero: qualquer
numero que seja divisível por outro terá como divisores
dois números ou fatores, e um será maior que o outro,
a não ser que tais números sejam iguais (quando o
numero tem uma raiz quadrada exata). No caso de
divisores diferentes, o numero menor sempre será
menor que a raiz quadrada do resultado da
multiplicação e o numero maior, maior que a raiz
quadrada do numero em questão.
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
26
Lógica de Programação I
Comandos de Repetição
Podemos perceber que quanto maior um dos fatores, menor
o outro. A relação if inverte após a linha da raiz quadrada,
quando os números if repetem em ordem inversa.
Podemos, então, concluir que if um numero não for divisível
por um numero menor ou igual à sua raiz quadrada, não terá
outro divisor que não ele próprio ou o 1. ou seja, será um
numero primo.****Portanto, só precisamos testar a
divisibilidade de um numero por valores iguais ou inferiores à
sua raiz quadrada. Adaptando o algoritmo, teremos o que if vê
no exemplo a seguir.
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
27
Lógica de Programação I
Comandos de Repetição
LP1_17
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
28
Lógica de Programação I
Comandos de Repetição
LP1_17
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
29
Lógica de Programação I
Produzindo conhecimento, transformando vidas
www.posse.ueg.br
30
Download