• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Cap04
 

Cap04

on

  • 844 views

 

Statistics

Views

Total Views
844
Views on SlideShare
844
Embed Views
0

Actions

Likes
0
Downloads
14
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Cap04 Cap04 Document Transcript

    • Capítulo 4DESENVOLVENDO ALGORITMOS Algoritmo é formalmente uma seqüência finita de passos que levam a execução de umatarefa. Podemos pensar em algoritmo como uma receita, uma seqüência de instruções que dãocabo de uma meta específica. Estas tarefas não podem ser redundantes nem subjetivas na suadefinição, devem ser claras e precisas. Algoritmo é a lógica necessária para o desenvolvimento deum programa. Programas de computadores nada mais são do que algoritmos escritos numa linguagem decomputador (Pascal, C, Cobol, Fortran, Visual Basic, entre outras) e que são interpretados eexecutados por uma máquina, no caso um computador. Notem que dada esta interpretaçãorigorosa, um programa é por natureza muito específico e rígido em relação aos algoritmos da vidareal. Em um modo geral, um algoritmo segue um determinado padrão de comportamento, comobjetivo de alcançar a solução de um problema. Padrão de comportamento: imagine a seqüência de números: 1, 6, 11, 16, 21, 26, ... Paradeterminar qual será o sétimo elemento dessa série, precisamos descobrir qual é a sua regra deformação, isto é, qual é o seu padrão de comportamento. Como a seqüência segue uma certaconstância, facilmente determinada, somos capazes de determinar qual seria o sétimo termo ououtro 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 percebermosos pequenos detalhes. Vejamos como seria descrevê-la passo a passo:pegar uma escada;posicionar a escada embaixo da lâmpada;buscar uma lâmpada nova;subir na escada;retirar a lâmpada velha;colocar a lâmpada nova. Para se trocar a lâmpada, é seguida uma determinada seqüência de ações, representadasatravés desse algoritmo. Como isso pode ser seguido por qualquer pessoa, estabelece-se aí umpadrão de comportamento. A sequencializaçã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âmpadanão estiver queimada? O algoritmo faz com ela seja trocada do mesmo modo, não prevendo essasituação. Para solucionar este problema, podemos efetuar um teste seletivo, verificando se alâmpada está ou não queimada:
    • pegar uma escada;posicionar embaixo da lâmpada;buscar uma lâmpada nova;ligar o interruptor;se a lâmpada não acender, então: subir na escada; retirar a lâmpada velha; colocar a lâmpada nova. Dessa forma, algumas ações estão ligadas à condição (lâmpada não acender). No caso dalâmpada acender, as três linhas não serão executadas. Em algumas situações, embora o algoritmo resolva o problema proposto, a solução podenão ser a mais eficiente. Exemplo: três alunos devem resolver um determinado problema:  O aluno A conseguiu resolver o problema executando 35 linhas de programa.  O aluno B resolveu o problema executando 10 linhas de programa  O aluno C resolveu o problema executando 54 linhas de programa. Obviamente, o algoritmo desenvolvido pelo aluno B é menor e mais eficiente que osdemais. Isso significa que há código desnecessário nos demais programas. Dessa forma, podemos otimizar o algoritmo anterior, uma vez que buscamos a escada e alâmpada sem saber se serão necessárias:ligar o interruptor;se a lâmpada não acender, então: pegar uma escada; posicionar a escada embaixo da lâmpada; buscar uma lâmpada nova; subir na escada; retirar a lâmpada velha; colocar a lâmpada nova. Podemos considerar ainda que a lâmpada nova pode não funcionar. Nesse caso devemostrocá-la novamente, quantas vezes for necessário, até que a lâmpada acenda:ligar o interruptor;se a lâmpada não acender, então: pegar uma escada; posicionar a escada embaixo da lâmpada; buscar uma lâmpada nova; subir na escada; retirar a lâmpada velha; colocar a lâmpada nova; se a lâmpada não acender, então: retirar a lâmpada; colocar outra lâmpada; se a lâmpada não acender, então: ...
    • Observamos que o teste da lâmpada nova é efetuado por um conjunto de ações:  se a lâmpada não acender então:  retirar a lâmpada  colocar outra lâmpada Em vez de escrevermos várias vezes este conjunto de ações, podemos alterar o fluxosequencial de execução do programa, de forma que, após executar a ação “coloque outralâmpada”, voltemos a executar a ação “se a lâmpada não acender”. Precisa-se então determinar um limite para tal repetição, para garantir que ela cessequando a lâmpada finalmente acender:enquanto a lâmpada não acender, faça: retire a lâmpada coloque outra lâmpada Uma versão final do algoritmo, que repete ações até alcançar o seu objetivo: trocar alâmpada queimada por uma que funcione, é apresentada abaixo.ligar o interruptor;se a lâmpada não acender, então: pegar uma escada; posicionar a escada embaixo da lâmpada; buscar uma lâmpada nova; subir na escada; retirar a lâmpada velha; colocar a lâmpada nova; enquanto a lâmpada não acender, faça: retirar a lâmpada; colocar outra lâmpada. Até agora, estamos efetuando a troca de uma única lâmpada. Todo o procedimentopoderia ser repetido 10 vezes, por exemplo, no caso de querermos trocar 10 lâmpadas.Inicialmente, tínhamos um pequeno conjunto de ações que deveriam ser executadas (estruturasequencial). Através de uma condição, incluímos posteriormente uma estrutura de seleção. Nanecessidade de repetir um determinado trecho do algoritmo, construiu-se no final uma estruturade repetição.
    • 1. FATORES A SEREM LEVADOS EM CONSIDERAÇÃO NA CONSTRUÇÃO DE UMALGORITMO1.1. COMPLEXIDADE Percebeu-se, na medida em que colocávamos situações novas no problema a ser resolvido,que ia aumentando a complexidade do algoritmo. Esse certamente é o maior problema envolvidona 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 serprevistas na sua solução. Já que conviver com a complexidade é um mal necessário, é saudável fazer o possível paradiminuí-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 deum devido problema desnecessariamente. A forma errada de interpretação de um problema podelevar a respostas irrelevantes à solução almejada ou até mesmo a nenhuma solução, gerandoalgoritmos mais complexos do que o necessário. Exemplo: digamos que se pergunte a um leigo a respeito de um relógio: - Como é um relógio? = É um instrumento com três ponteiros concêntricos. Como a descrição não é relevante, poderíamos indagar: - Um relógio com 2 ponteiros é possível? = É... pode ser! 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. - E sem ponteiro pode? = Ah!, Sim! Pode ser digital 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 sistemaquando forem bem ou mal utilizadas.1.2. LEGIBILIDADE Mede a capacidade de compreensão de um algoritmo por qualquer observador (que não oconstruiu); a clareza com que sua lógica está exposta. Quanto mais legível for um algoritmo,menor será sua complexidade.
    • 1.3. PORTABILIDADE Devido a quantidade enorme de linguagens de programação existentes, não será adotadanenhuma linguagem específica para trabalhar os algoritmos (ex: C, pascal, Java, etc.). Isso porquea solução do problema fica ligada a características e recursos da linguagem na qual ela foiconcebida. Utilizaremos uma pseudo-linguagem (linguagem fictícia) que visa a permitir arepresentação dos algoritmos através da língua portuguesa (português estruturado). Essesalgoritmos poderão ser convertidos facilmente para qualquer linguagem de programação usual(Basic estruturado, C, pascal, Java).1.4. TÉCNICA DE RESOLUÇÃO POR MÉTODO CARTESIANO A famosa frase de Descartes “Dividir para conquistar” é muito importante dentro daprogramação. É um método que ataca um problema grande, de difícil solução, dividindo-o emproblemas menores, de solução mais fácil. Se necessário, pode-se dividir novamente as partes nãocompreendidas. 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. 3. Reaplicar o método, se necessário1.5. PLANEJAMENTO REVERSO Consiste em, a partir do resultado final, determinar quais são os componentes básicos. Ouseja, a partir da saída desejada, devemos poder determinar, reversamente, quais são oscomponentes da entrada de dados necessários.2. MÉTODO PARA CONSTRUIR UM ALGORITMO Para escrever um algoritmo precisamos descrever a seqüência de instruções, de maneirasimples e objetiva. Para isso utilizaremos algumas técnicas:  Usar somente um verbo por frase  Imaginar que você está desenvolvendo um algoritmo para pessoas que não trabalham com informática  Usar frases curtas e simples  Ser objetivo  Procurar usar palavras que não tenham sentido dúbio Utilizando os conceitos já desenvolvidos, esquematizaremos um método para construir umalgoritmo logicamente correto:
    • 1. Ler atentamente o enunciadoDeve-se reler o enunciado de um exercício quantas vezes for necessário, até compreendê-locompletamente. A maior parte da resolução de um exercício consiste na compreensão completado enunciado.2. Retirar a relação das entradas de dados do enunciadoAtravés do enunciado, descobrimos quais são os dados que devem ser fornecidos ao programa, viateclado, a partir dos quais são desenvolvidos os cálculos. Obs. Pode haver algum algoritmo quenão necessite da entrada de dados (pouco comum).3. Retirar do enunciado, a relação das saídas das informaçõesAtravés do enunciado podemos descobrir quais são as informações que devem ser mostradas paracompor o resultado final, objetivo do algoritmo.4. Determinar o que deve ser feito para transformar as entradas nas saídas especificadasNessa fase é que teremos a construção do Algoritmo propriamente dito. Devemos determinarqual sequência de passos ou ações é capaz de transformar um conjunto de dados nas informaçõesde resultado. Para isso, utilizamos os fatores descritos anteriormente, tais como legibilidade,portabilidade, método cartesiano e planejamento reverso, e finalmente podemos construir oalgoritmo.2.1. FASES Vimos que ALGORITMO é uma seqüência lógica de instruções que podem ser executadas. Éimportante ressaltar que qualquer tarefa que siga determinado padrão pode ser descrita por umalgoritmo, como por exemplo: COMO FAZER ARROZ DOCE ou então CALCULAR O SALDO FINANCEIRO DE UM ESTOQUE Entretanto ao montar um algoritmo, precisamos primeiro dividir o problema apresentadoem três fases fundamentais. Onde temos: ENTRADA: São os dados de entrada do algoritmo PROCESSAMENTO: São os procedimentos utilizados para chegar ao resultado final SAÍDA: São os dados já processados
    • Analogia com o homem2.2. EXEMPLO DE ALGORITMO Imagine o seguinte problema: Calcular a média final dos alunos da 3ª Série. Os alunosrealizarão quatro provas: P1, P2, P3 e P4. Onde: Para montar o algoritmo proposto, faremos três perguntas: a) Quais são os dados de entrada? R: Os dados de entrada são P1, P2, P3 e P4 b) Qual será o processamento a ser utilizado? R: O procedimento será somar todos os dados de entrada e dividi-los por 4 (quatro) c) Quais serão os dados de saída? R: O dado de saída será a média finalAlgoritmo:Receba a nota da prova1Receba a nota de prova2Receba a nota de prova3Receba a nota da prova4Some todas as notas e divida o resultado por 4Mostre o resultado da divisão
    • 2.3. TESTE DE MESA Após desenvolver um algoritmo ele deverá sempre ser testado. Este teste é chamado deTESTE DE MESA, que significa, seguir as instruções do algoritmo de maneira precisa para verificarse o procedimento utilizado está correto ou não. Veja o exemplo utilizando a tabela abaixo: P1 P2 P3 P4 Média3. MÁXIMAS DE PROGRAMAÇÃO “Máximas de Programação” são regras práticas para a elaboração de algoritmos comqualidade. Alguns exemplos são apresentados a seguir. 1. Algoritmos devem ser feitos para serem lidos por seres humanos: tenha em mente que seus algoritmos deverão ser lidos e entendidos por outras pessoas (e por você mesmo), de tal forma que possam ser corrigidos, modificados, ou receber manutenção; 2. Escreva os comentários no momento em que estiver escrevendo o algoritmo: um algoritmo não documentado é um dos piores erros que um programador pode cometer; é sinal de amadorismo. Como o objetivo da escrita de comentários é facilitar o entendimento do algoritmo, eles devem ser tão bem concebidos quanto o próprio algoritmo, e a melhor maneira de conseguir isso é escrevê-los nos momentos de maior intimidade com os detalhes, ou seja, durante a resolução do problema. Lembre-se: é melhor ter um algoritmo sem comentários do que ter um algoritmo com comentários desatualizados; 3. Os comentários deverão acrescentar alguma coisa às pessoas que farão manutenção em seu algoritmo: o conjunto de comandos nos diz o que está sendo feito; os comentários deverão nos dizer o porquê; 4. Use comentários no cabeçalho do algoritmo: todo algoritmo ou procedimento deverá ter comentários em seu início para explicar o que ele faz e fornecer instruções para seu uso. Alguns destes comentários seriam: a. Uma descrição do que faz o algoritmo; b. Como utilizá-lo; c. Explicação dos significados das variáveis mais importantes;
    • d. Estruturas de dados utilizadas; e. Data da escrita; f. Autor; g. Nomes de quaisquer métodos especiais utilizados, como referências nas quais mais informações possam ser encontradas.5. Utilize espaços em branco para melhorar a legibilidade: espaços em branco, inclusive linhas em branco, são muito valiosos, pois melhoram a aparência de um algoritmo. Veja: a. Deixar uma linha em branco entre as declarações e o corpo do algoritmo; b. Deixar uma linha em branco antes e outra depois de um comentário; c. Separar grupos de comandos que executam funções lógicas distintas por uma ou mais linhas em branco; d. Utilizar brancos para indicar precedências de operadores. Em vez de “A + B * C” é bem mais agradável a forma “A + B*C”.6. Escolha nomes representativos para suas variáveis: os nomes das variáveis deverão identificar o melhor possível as funcionalidades que elas representam. Por exemplo, X <- Y + Z é muito menos claro que PREÇO <- CUSTO + LUCRO. Uma seleção adequada de nomes de variáveis é o princípio mais importante da legibilidade de algoritmos;7. Um comando por linha é suficiente: a utilização de vários comandos por linha é prejudicial, por várias razões, entre as quais se destacam: a. O algoritmo pode ficar ilegível; b. O algoritmo fica mais difícil de ser depurado. Veja um exemplo: A <- 14, 2 ; I<-1; enquanto I<10 faça X <- X + 1 ; K<-I*K;I<-I+1 fim-enquanto; Agora, com cada comando em uma linha: A <- 14,2 I <- 1 enquanto I<10 faça X <- X + 1 K <- I * K I <- I + 1 fim-enquanto; Caso desejássemos incluir um novo comando dentro do enquanto, seria necessário reescrever toda a linha.
    • 8. Utilize parênteses para aumentar a legibilidade e prevenir-se contra erros. Veja uns exemplos, primeiro, com pouco parênteses: A * B * C / (D * E * F) A * B / C * D / E * F A / B / C / D X > Y ou Q A + B < C Agora, com parênteses extras: (A * B * C) / (D * E * F) ((((A * B) / C) * D) / E) * F ((A / B) / C) / D (X > Y) ou Q (A + B) < C 9. Utilize “identação” para montar a estrutura lógica do algoritmo: a identação não deve ser feita de forma caótica, mas segundo certos padrões estabelecidos; 10. Sempre que for feita uma modificação no algoritmo, os comentários associados devem ser alterados, e não apenas os comandos. Antes não comentar do que deixar um comentário errado. Para concluir, vamos ver um trecho de um algoritmo mal escrito. A análise das regras deprogramação violadas será apresentada a seguir. inicio inteiro: XPT, I, II, III, IIIII leia (XPT, IIIII) I <- 1 enquanto I < XPT faça se I < IIIII então se IIIII = 20 então II <- XPT + 2 senão III <- IIIII ^ XPT; senão III <- XPT IIIII <- III + I; fim-se; fim-se; //sem comentários I <- I + 1 fim-enquanto; imprima (I, II, IIIII, III, XPT); fim. Esse código fere todas as regras pregadas pelas máximas de programação, sendo que asmais graves são: falta de identação, nomes não significativos para as variáveis e ausência decomentários.
    • EXERCÍCIOS PROPOSTOSQuestão 01:Um homem ia pela estrada transportando para vender na cidade um LOBO, um CORDEIRO, cadaqual por uma coleira, e um SACO DE COUVES nas costas. Em determinada etapa do caminhodeparou-se com um rio com uma canoa muito pequena onde cabiam ele e apenas mais um dostrês itens que transportava de cada vez. Ora, ele tinha o problema de vigiar o cordeiro que estavadoido pra comer as couves e lógico um lobo louco pra comer o cordeiro. Tendo que atravessar umde cada vez, não podia deixar juntos em qualquer margem do rio, o lobo com o cordeiro e nem ocordeiro com as couves. Como o homem conseguirá atravessar o rio sem perder nenhum de seusitens? Monte um algoritmo que descreva os passos desse homem para atravessar o rio.Questão 02: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 menoressobre os maiores. Pode-se mover um disco de cada vez para qualquer haste, sendo que nuncadeve ser colocado um disco maior sobre um menor. O objetivo é transferir os três discos da hasteA para haste C.