Algoritmo Iterativo Fernando Cardeal Parece com o processo de seguir uma estrada: Como chegar à estrada? Como se manter na estrada? Como saber que chegou ao destino para sair da estrada? Como fazer tudo isso em um tempo razoável? Fernando Cardeal 2 Dilema do Martelo x Edifício O Martelo O Martelo representa os detalhes. É muito comum um iniciante em programação se preocupar com: Detalhes do ambiente de desenvolvimento; Detalhes da sintaxe da linguagem de programação; Definição de que comandos usará. Tudo isso é importante, mas, será que devemos iniciar por aí? Fernando Cardeal 3 Fernando Cardeal 4 O Edifício O Edifício representa o Problema que queremos resolver; Antes de pensarmos em ferramentas, em detalhes (que são muito importantes), devemos pensar no objetivo que pretendemos alcançar. Dilema das ações x declarações É muito comum um programador iniciar um algoritmo pensando em declarações. Declaração: float salario; scanf( %f,&salario); Ação: Ler o valor do salário Fernando Cardeal 5 Fernando Cardeal 6 1
Paradigmas Sequência de declarações/comandos; Sequência de ações; Sequência de estados instantâneos. Fernando Cardeal 7 Fernando Cardeal 8 Características do Algoritmo Finitude: um algoritmo tem de terminar ao fim de um número finito de passos. Definitude: cada passo do algoritmo tem de ser definido com precisão. Entrada: um algoritmo pode ter zero ou mais entradas. Saídas: um algoritmo tem uma ou mais saídas. Eficácia: todas as operações feitas por um algoritmo têm de ser básicas. Considerações para o desenvolvimento Invariante de laço: relações entre as variáveis que devem ser verdadeiras no início de cada iteração e ao final do laço. Demonstração de Correção: o algoritmo precisa funcionar para todas as entradas especificadas e deve fornecer as respostas corretas. Tempo de Processamento: o algoritmo deve terminar em um tempo razoável. Fernando Cardeal 9 Fernando Cardeal 10 Passos para desenvolver um algoritmo iterativo Não se deve começar um algoritmo digitando o código sem saber como ele realmente irá funcionar. É preciso estabelecer vários aspectos para garantir o seu funcionamento: Especificações; Passos básicos; Medida de progresso; Invariante de laço; Passos principais; Controle de progresso. Fernando Cardeal 11 Fernando Cardeal 12 2
ESPECIFICAÇÕES Que problema você está resolvendo? Quais são as precondições? Condições iniciais, situação inicial. Quais são as pós-condições? Qual o destino? Qual a situação desejada? PASSOS BÁSICOS Quais são os passos básicos que vão levar você na direção certa? Que considerações devem ser feitas? Fernando Cardeal 13 Fernando Cardeal 14 MEDIDA DE PROGRESSO Como controlar o progresso do algoritmo? Quais são os marcadores de quilômetros da estrada? PASSOS PRINCIPAIS É necessário escrever o código que fará o algoritmo avançar, dar um passo. Sugestão: em vez de começar no início do algoritmo, pense como seria um passo típico no meio da computação. Fernando Cardeal 15 Fernando Cardeal 16 CONTROLE DE PROGRESSO A cada iteração do seu passo principal, lembre-se de fazer progresso de acordo com a sua medida de progresso. A FALTA DESSE CONTROLE É UM DOS ENGANOS MAIS COMUNS. Fernando Cardeal 17 Fernando Cardeal 18 3
O CASO DAS ALTURAS DE CHICO E ZÉ Chico mede 1,30 m de altura e cresce 2 centímetros por ano, enquanto Zé mede 1,10 m de altura e cresce 3 centímetros por ano. Faça um algoritmo que calcule e exiba quantos anos serão necessários para que Zé seja mais alto do que Chico. O algoritmo também deve exibir as alturas finais de Chico e de Zé quando ocorrer a ultrapassagem. ESPECIFICAÇÕES O que quero resolver? Leia o problema novamente: Chico mede 1,30 m de altura e cresce 2 centímetros por ano, enquanto Zé mede 1,10 m de altura e cresce 3 centímetros por ano. Faça um algoritmo que calcule e exiba quantos anos serão necessários para que Zé seja mais alto do que Chico. O algoritmo também deve exibir as alturas finais de Chico e de Zé quando ocorrer a ultrapassagem. Fernando Cardeal 19 Fernando Cardeal 20 ESPECIFICAÇÕES Precondições: Condição Valor Altura Chico 1,30m Altura Zé 1,10m Crescimento Chico 2 cm/ano Crescimento Zé 3 cm/ano PASSOS BÁSICOS As alturas foram dadas em metro e o crescimento em centímetros. Ajustar as unidades de medida inicialmente. A cada ano que passa, aumentar a altura de Chico e aumentar a altura de Zé. Pós-condições: Zé fica mais alto do que Chico Fernando Cardeal 21 Fernando Cardeal 22 MEDIDA DE PROGRESSO A altura de Zé se aproxima da altura de Chico a cada ano. Contar os anos a cada crescimento. INVARIANTE DE LAÇO Como controlar para determinar quando devo ficar e quando devo sair do laço? Quando Zé for maior do Chico, sair do laço. Assim... Enquanto a altura de Zé for menor ou igual à altura de Chico eu permaneço. Fernando Cardeal 23 Fernando Cardeal 24 4
PASSOS PRINCIPAIS Os passos da lógica principal. A cada ano acrescentar 3cm à altura de Zé e 2cm à altura de Chico. CONTROLE DE PROGRESSO A cada crescimento somar 1 ao contador de tempo (ano). Fernando Cardeal 25 Fernando Cardeal 26 ALGORITMO PRONTO INÍCIO inteiro AltChico, AltZe, Tempo AltChico = 130 // optei por cm AltZe = 110 Tempo = 0 // inicialmente Enquanto (AltZe <= AltChico) AltChico = AltChico + 2 AltZe = AltZe + 3 Tempo = Tempo + 1 // olha o progresso! Fim-Enquanto Exiba "Tempo necessario: ", Tempo Exiba "Altura de Chico: ", AltChico Exiba "Altura de Zé: ", AltZe FIM Fernando Cardeal 27 Fernando Cardeal 28 O caso da Companhia FearToFly Escreva um programa que controle a reserva de passagens da companhia aérea FearToFly. O controle deve ser feito da seguinte forma: Existem 10 voos numerados de 1 a 10 e todas as aeronaves são iguais, cada uma delas comportando 20 passageiros. Ler uma quantidade indeterminada de pedidos de reserva para uma vaga no voo (X). O programa deve parar quando X for zero. Cada pedido de reserva é para apenas 1 vaga. Uma vez lido o pedido de reserva, o programa deve verificar se o voo existe e se tem vaga nele. Se o voo existir e houver vaga, deve abater essa reserva das vagas disponíveis nesse voo. Se o voo não existir (por exemplo, voo 5400) ou se não houver vagas no voo desejado, deve emitir mensagem adequada à situação. Ao finalizar, o programa deve exibir o número de vagas que ficaram disponíveis em cada um dos voos da companhia. ESPECIFICAÇÕES OBJETIVOS: Fazer reservas de passagens controlando o número de vagas nos voos disponíveis. PRECONDIÇÕES: Existem 10 voos Cada aeronave comporta 20 passageiros Pedidos de reserva informam número de voo válido (1 a 10). PÓS-CONDIÇÕES: Vagas atualizadas em cada voo. Mensagens de erro se não houver vaga ou se voo não existir. Saldo de vagas em cada voo no final. Fernando Cardeal 29 Fernando Cardeal 30 5
PASSOS BÁSICOS No início criar tabela de voos e preencher com as vagas (20 para cada voo). Atualizar as vagas a cada pedido de reserva. MEDIDA DE PROGRESSO Pedidos de reserva são lidos e processados se forem válidos. Cada pedido é de apenas uma vaga em cada voo. Fernando Cardeal 31 Fernando Cardeal 32 INVARIANTE DE LAÇO Pedidos devem ser processados até ser encontrado o pedido de reserva para o voo zero. Então: enquanto voo diferente de 0. PASSOS PRINCIPAIS Montar inicialmente a tabela de voos. Um array? Como? Para cada pedido de reserva (número do voo X) Verificar se é válido e, se não for, emitir mensagem de erro. Verificar se existe vaga: Se existir, atualizar. Se não existir, dar mensagem de erro Fernando Cardeal 33 Fernando Cardeal 34 CONTROLE DE PROGRESSO Verificar se foi lido o voo zero. Lembrar de exibir o saldo de vagas ao final A solução pronta em C #include <iostream> using namespace std; int main() { int MAX=11; // para eliminar o ind=0 int capacidade=20; // capacidade de cada aeronave int vagas[max], voo, i; // preenche as vagas iniciais dos voos. for (i=1; i<max; i++ ) { vagas[i] = capacidade; // preenche as vagas para todos os voos. cout << "Informe o voo desejado (0 para terminar): "; cin >> voo; Fernando Cardeal 35 Fernando Cardeal 36 6
while (voo!= 0) { if (voo < 0 voo > (MAX-1)) { cout << "\n Voo " << voo << " nao existe. Tente de novo!\n"; else { if (vagas[voo] > 0) { // tem vaga no voo vagas[voo] = vagas[voo] - 1; // abate a vaga cout << " Vaga reservada com sucesso\n"; else { // não tem vaga cout << "Voo " << voo << " nao tem mais vagas.\n"; cout << "Informe o voo desejado (0 para terminar): "; cin >> voo; // exibe as vagas restantes cout << "\n\nvagas RESTANTES:\n"; cout << "VOO\tVAGAS\n"; for (i=1; i<max; i++ ) { cout << i << "\t" << vagas[i] << "\n"; return 0; Fernando Cardeal 37 Fernando Cardeal 38 O caso do Monge esperto Uma rainha requisitou os serviços de um monge e disselhe que pagaria qualquer preço. O monge, necessitando de alimentos, perguntou à rainha se o pagamento poderia ser feito com grãos de trigo dispostos em um tabuleiro de xadrez de forma que o primeiro quadro contivesse apenas um grão e cada quadro subsequente contivesse o dobro do quadro anterior. A rainha considerou o pagamento barato e mandou executar o serviço, sem se dar conta que seria impossível efetuar o pagamento. Faça um algoritmo que calcule e exiba o número de grãos que o monge esperava receber Fernando Cardeal 39 Fernando Cardeal 40 O caso das resistências paralelas O caso da locadora boazinha Uma locadora de DVDs tem guardada, em um vetor de 50 posições, a quantidade de filmes retirados por seus clientes durante o ano. A locadora decidiu fazer uma promoção e, para cada 10 DVD retirados, o cliente tem direito a uma locação grátis. Desenvolva um algoritmo que crie outro vetor contendo a quantidade de locações gratuitas a que cada cliente tem direito, exibindo o resultado em seguida (apenas com aqueles clientes que têm direito a locações grátis). A posição do vetor corresponde ao código do cliente Fernando Cardeal 41 Fernando Cardeal 42 7
Encontrando a raiz de uma função qualquer Dada uma função f(x) qualquer, contínua no intervalo real [a,b], obter a raiz dessa função com tolerância TOL utilizando o método da bisseção. A teoria afirma que, se f(a).f(b) < 0, existe pelo menos uma raiz de f(x) em [a,b]. O método consiste em dividir o intervalo [a,b] sucessivamente pela metade (m) e tornar a verificar em que lado do intervalo a propriedade básica se mantém. [a,m] ou [m,b]. O lado que mantiver a propriedade será mantido e o outro descartado. Escreva um algoritmo que leia os valores limites do intervalo, a tolerância e o limite de iterações. Ao final, exiba a raiz obtida, o erro absoluto e o número de iterações realizadas. Caso a tolerância não seja atingida no limite de iterações informado emitir mensagem. AGORA É COM VOCÊS! Fernando Cardeal 43 Fernando Cardeal 44 8