Escolar Documentos
Profissional Documentos
Cultura Documentos
Introdução: Algoritmos
Introdução: Algoritmos
1. Introdução
2. Representação de Algoritmos
1. Linguagem Natural
2. Fluxogramas
3. Pseudo-Linguagem
3. A Pseudo-Linguagem do Visualg
1. Tipos de Dados
2. Variáveis
3. Expressões
1. Expressões Aritméticas
2. Expressões Lógicas
4. Comandos
4. Exemplos de Algoritmos
5. Exercícios
Introdução
Para resolver um problema no computador é necessário que seja primeiramente encontrada
uma maneira de descrever este problema de uma forma clara e precisa. É preciso que
encontremos uma seqüência de passos que permitam que o problema possa ser resolvido de
maneira automática e repetitiva. Além disto é preciso definir como os dados que serão
processados serão armazenados no computador. Portanto, a solução de um problema por
computador é baseada em dois pontos: a seqüência de passos e a forma como os dados
serão armazenados no computador. Esta seqüência de passos é chamada de algoritmo. Um
exemplo simples e prosaico, de como um problema pode ser resolvido caso forneçamos
uma seqüência de passos que mostrem a solução, é uma receita para preparar um bolo.
No seu livro Fundamental Algorithms vol. 1 Donald Knuth apresenta uma versão para a
origem desta palavra. Ela seria derivada do nome de um famoso matemático persa chamado
Abu Ja´far Maomé ibn Mûsâ al-Khowârism (825) que traduzido literalmente quer dizer Pai
de Ja´far, Maomé, filho de Moisés, de Khowârizm. Khowârizm é hoje a cidade de Khiva,
na ex União Soviética. Este autor escreveu um livro chamado Kitab al jabr w´al-muqabala
(Regras de Restauração e Redução). O título do livro deu origem também a palavra
Álgebra.
Um algoritmo opera sobre um conjunto de entradas (no caso do bolo, farinha ovos,
fermento, etc.) de modo a gerar uma saída que seja útil (ou agradável) para o usuário (o
bolo pronto). Um algoritmo tem cinco características importantes:
Finitude:
Um algoritmo deve sempre terminar após um número finito de passos.
Definição:
Cada passo de um algoritmo deve ser precisamente definido. As ações devem ser
definidas rigorosamente e sem ambiguidades.
Entradas:
Um algoritmo deve ter zero ou mais entradas, isto é quantidades que são lhe são
fornecidas antes do algoritmo iniciar.
Saídas:
Um algoritmo deve ter uma ou mais saídas, isto é quantidades que tem uma relação
específica com as entradas.
Efetividade:
Um algoritmo deve ser efetivo. Isto significa que todas as operações devem ser
suficientemente básicas de modo que possam ser em princípio executadas com
precisão em um tempo finito por um humano usando papel e lápis.
É claro que todos nós sabemos construir algoritmos. Se isto não fosse verdade, não
conseguiríamos sair de casa pela manhã, ir ao trabalho, decidir qual o melhor caminho para
chegar a um lugar, voltar para casa, etc. Para que tudo isto seja feito é necessário uma série
de entradas do tipo: a que hora acordar, que hora sair de casa, qual o melhor meio de
transporte, etc.
Um fator importante é que pode haver mais de um algoritmo para resolver um determinado
problema. Por exemplo, para ir de casa até o trabalho, posso escolher diversos meios de
transporte em função do preço, conforto, rapidez, etc. A escolha será feita em função do
critério que melhor se adequar as nossas necessidades.
Um exemplo de algoritmo pode ser as instruções que um professor passa aos seus alunos
em uma academia de ginástica. Por exemplo:
Para mostrar outro exemplo de algoritmo considere o seguinte problema. Dispomos de duas
vasilhas com capacidades de 9 e 4 litros respectivamente. As vasilhas não tem nenhum tipo
de marcação, de modo que não é possível ter medidas como metade ou um terço. Mostre
uma seqüência de passos, que usando as vasilhas de 9 e 4 litros encha uma terceira vasilha
de medida desconhecida com seis litros de água.
Um outro exemplo de algoritmo é o que resolve o seguinte problema. Considere cinco rãs
estão posicionadas em seis casas da seguinte maneira:
rã 1 rã 2 rã 3 rã 4 rã 5
As rãs foram treinadas para trocar de casas, mas sempre obedecendo as seguintes regras:
• elas podem pular para a casa vizinha (frente ou trás), se ela estiver vazia;
• elas podem pular sobre a rã vizinha para uma casa livre (frente ou trás).
rã 5 rã 4 rã 3 rã 2 rã 1
• Início do algoritmo.
o Pegue a primeira temperatura registrada.
o Anote esta temperatura como a menor de todas as temperaturas.
o Enquanto ainda houver registros de temperaturas, execute repetidamente e
em ordem todas as instruções numeradas abaixo:
1. Pegue a próxima temperatura.
2. Se esta temperatura for menor que àquela registrada no momento
como a menor então
jogue fora a anteriormente registrada e anote a nova temperatura
como a menor de todas.
o Leia a temperatura que está anotada como a menor. Esta é a temperatura que
estávamos procurando.
• Fim do algoritmo.
Este algoritmo faz o seguinte. Pega a primeira temperatura e a anota como a menor já
encontrada. A partir daí o algoritmo fica repetidamente lendo temperaturas dos registros do
escritório comparando com a temperatura que no momento consta como a menor de todas.
Se a temperatura tirada dos arquivos for menor que a menor atual, o algoritmo joga fora a
temperatura anotada e guarda a que foi lida como a nova menor temperatura. Quando não
houver mais temperaturas para ler a que estiver anotada como a menor é a menor
verdadeiramente.
Neste algoritmo mostramos como pode-se escrever um algoritmo para tratar e processar
números, no caso temperaturas. Esta não é a única solução possível e poderíamos imaginar
outras. Além disso, temos a forma como o algoritmo foi escrito. Esta maneira é uma das
maneiras que dispomos para descrever algoritmos. Este algoritmo foi descrito em
linguagem natural, ou seja a linguagem que normalmente usamos para nos comunicarmos.
Na próxima seção iremos mostrar outras maneiras que podem ser usadas para escrever
algoritmos.
Representação de Algoritmos
As formas mais comuns de representação de algoritmos são as seguintes:
Linguagem Natural
Os algoritmos são expressos diretamente em linguagem natural, como nos exemplos
anteriores.
Fluxograma Convencional
Esta é um representação gráfica que emprega formas geométricas padronizadas para
indicar as diversas ações e i decisões que devem ser executadas para resolver o
problema.
Pseudo-linguagem
Emprega uma linguagem intermediária entre a linguagem natural e uma linguagem
de programação para descrever os algoritmos.
Não existe consenso entre os especialistas sobre qual seria a melhor maneira de representar
um algoritmo. Atualmente a maneira mais comum de representar-se algoritmos é através de
uma pseudo-linguagem ou pseudo-código. Esta forma de representação tem a vantagem de
fazer com que o algoritmo seja escrito de uma forma que está próxima de uma linguagem
de programação de computadores. Algoritmo de encontrar a menor temperatura dentro de
registros de temperaturas mostrada na seção anterior usou linguagem natural para
representar o algoritmo.
Linguagem Natural
Como ilustração de algoritmo em linguagem natural vamos considerar a receita abaixo. Por
economia de texto e facilidade a receita não mostra as quantidades dos ingredientes (as
entradas). Alguns mais maldosos dizem que o cozinheiro não quis divulgar o seu segredo.
Observe que a receita foi subdividida em partes: preparo dos peixes, preparo do molho
branco e finalmente juntar as duas partes. Esta é uma técnica comum na resolução de
problemas: dividir para conquistar. Vamos considerar agora uma outra receita que tenha
molho branco como parte, para ilustrar uma outra técnica comum da criação e descrição de
algoritmos. A próxima receita é esta:
• Molho branco
o Coloque numa panela a manteiga, a farinha e o leite e misture bem. Em fogo
médio, cozinhe até engrossar. Adicione o sal, a pimenta e o queijo. Continue
com a panela no fogo, cozinhando até que o queijo derreta, mexendo
constantemente.
• Fim da receita do molho branco
Observe a economia de linhas de texto que foi possível devido a separação da receita de
molho branco das demais. Se o mesmo procedimento for seguido para as demais receitas
básicas, é de se esperar que o livro fique mais "fininho" do que antes.
Você pode argumentar que, no método anterior, era mais rápido seguir uma receita. Agora,
ao preparar o peixe ao molho branco, por exemplo, você tem de interromper a leitura,
marcar a página onde você estava, abrir na página da receita de molho branco, aprender a
prepará-lo e, então, retornar à receita do peixe. Você tem razão, mas, além da economia de
papel, existem outras vantagens em separar a receita do molho branco. Imagine, por
exemplo, que amanhã você descubra que o molho branco fica uma delícia se levar uma
pitada de alho. Basta modificar a receita de molho branco, que aparece em um único lugar
no livro, e todas as receitas "ao molho branco" estarão automaticamente modificadas. No
método anterior, seria preciso modificar todas as receitas que usam molho branco, com o
risco considerável de esquecermos de modificar alguma delas.
Você prestou atenção? Ao invés de ensinar a preparar molho branco, a receita instrui você a
comprá-lo pronto, no supermercado. Ou, em outras palavras, é possível usar no preparo do
seu prato, ingredientes já prontos, preparados por outra pessoa, que você talvez nem
conheça. Além disso, se você não é um cozinheiro experiente, o molho à venda no
supermercado já foi suficientemente testado e é, provavelmente, gostoso. Embora, nem
todos vão concordar com tal infâmia! Você já tem problemas suficientes tentando preparar
um bom peixe. Talvez seja melhor usar o molho do supermercado e não ter de se preocupar
com essa parte do problema. O uso de algoritmos criados por outros é muito comum na
informática e pode reduzir consideravelmente o tempo de criação de um sistema.
Toda a discussão acima tem uma forte analogia com o estudo de algoritmos e técnicas de
programação. Isto ficará mais claro para você mais tarde, quando estudarmos
procedimentos e funções.
Para ilustrar mais um conceito importante de algoritmos vamos analisar mais um exemplo,
considerando o problema de calcular a área de uma mesa retangular. Este cálculo pode ser
efetuado se seguirmos os seguintes passos.
Vamos supor agora que dispomos de uma mesa e de uma toalha cobrindo esta mesa e
gostaríamos de saber as áreas da toalha e da mesa. O algoritmo pode ser escrito da seguinte
maneira.
Observe que os algoritmos para cálculo da área da mesa e da toalha são parecidos, trazendo
a idéia que existe um algoritmo mais geral que é o de cálculo da área de um objeto
retangular. Este algoritmo mais geral pode ser então aplicado tanto à mesa como à toalha.
O algoritmo para cálculo da área da mesa e da toalha poderia ser reescrito de forma mais
compacta com as seguintes instruções:
Observe que neste caso um mesmo algoritmo pode ser aplicado a diferentes objetos,
reduzindo o número de algoritmos a serem definidos.
A maioria dos algoritmos contém decisões, por exemplo, para atravessar uma rua preciso
verificar se o sinal de pedestres está verde e verificar se nenhum carro está avançando o
sinal, somente após decidir se estes fatos se confirmaram poderei atravessar a rua.
Para considerar um algoritmo que inclua decisões vamos estudar um algoritmo que nos
ajude a decidir o que fazer em um domingo. Um possível algoritmo poderia ser o seguinte:
• Algoritmo de domingo.
o Acordar.
o Tomar o café.
o Se estiver sol vou à praia senão leio o jornal.
o Almoçar.
o Ir ao cinema.
o Fazer uma refeição.
o Ir dormir.
• Final do domingo.
ax2+bx+c=0
x1=[-b+(b2-4ac)(1/2)]/(2a)
x2=[-b-(b2-4ac)(1/2)]/(2a)
Neste algoritmo em diversos pontos tivemos de tomar decisões e indicar o que fazer em
cada uma das possibilidades, mesmo que seja mostrar que não podemos continuar o
algoritmo. Toda vez que decisões tiverem de ser tomadas devemos incluir todas as
possibilidades para o evento que estamos considerando.
Este é um dos possíveis algoritmos por diversas razões. Por exemplo, poderíamos incluir no
algoritmo o cálculo das raízes imaginárias ou no caso do coeficiente a ser igual a zero
calcular como se fosse uma equação do primeiro grau.
Fluxogramas
ax+b=0
que vale
x=-(b/a)
se a for diferente de zero. A Figura abaixo mostra um possível algoritmo para resolver este
problema.
Pseudo Linguagem
Este modo de representar algoritmos procura empregar uma linguagem que esteja o mais
próximo possível de uma linguagem de programação de computadores de alto nível mas
evitando de definir regras de construção gramatical muito rígidas. A idéia é usar as
vantagens do emprego da linguagem natural, mas restringindo o escopo da linguagem.
Normalmente estas linguagens são versões ultra reduzidas de linguagens de alto nível do
tipo Pascal ou C. No próximo capítulo veremos um exemplo de uma destas pseudo-
linguagens.
inicio
escreva(“Alo mundo.”)
fim
Tipos de Dados
Os algoritmos irão manipular dados, que normalmente são fornecidos pelos usuários, e
entregar resultados para estes usuários. Uma pergunta importante neste momento é: que
tipo de dados poderemos manipular? As linguagens de programação normalmente
estabelecem regras precisas para definir que tipos de dados elas irão manipular. A pseudo-
linguagem a-- também estabelece, ainda que informalmente, algumas regras que limitam o
conjunto de dados existentes na natureza e que poderão ser manipulados pelos algoritmos.
• Dados numéricos
• Dados alfa numéricos
• Dados Lógicos
Dados Numéricos
• Dados inteiros
• Dados reais
O conjunto dos dados inteiros pode ser definido como Z={...,-3,-2,0,1,2,...}. O conjunto dos
números reais inclui o conjunto dos números inteiros, dos números fracionários e dos
números irracionais. O conjunto dos números fracionários pode ser formalmente definido
como Q={p/q | p,q pertencem a Z}. O conjunto dos números irracionais engloba aqueles
que não podem ser representados por uma fração, por exemplo o número PI=3.141515... Os
números irracionais são armazenados até um certo número de casas decimais que o
computador consegue representar a partir daí as casas decimais são descartadas.
Neste ponto é importante lembrar que dois fatos importantes. Primeiro computadores
trabalham com uma base diferente de 10. Computadores trabalham em base 2 e no processo
de conversão entre a base 10 e a base 2 podem ocorrer problemas de perda de dígitos
significativos. Por exemplo, o número real 0.6 ao ser convertido para a base dois gera uma
dízima periódica. Outro fato importante é que a memória do computador é limitada e
portanto o número de dígitos binários que podem ser armazenados é função deste tamanho.
Deste modo o processo de conversão e desconversão entre bases pode causar perda de
informação.
O sinal de + e - entre colchetes significa que um número inteiro pode ou não ter sínal, isto é
o sinal é opcional. Em seguida temos um algarismo que é obrigatório. Isto é dados inteiros
tem de ter pelo menos um algarismo. A seguir temos a palavra algarismo entre chaves, o
que significa que um número inteiro deve ter pelo menos um algarismo e pode ser seguido
por uma seqüência de algarismos.
• +3
• 3
• -324
• 0.5
• +0.5
• -3.1415
Dados Alfa-numéricos
Dados alfa-numéricos servem para tratamento de textos e normalmente são compostos por
uma seqüência de caracteres contendo letras, algarismos e caracteres de pontuação. Nos
algoritmos são normalmente representados por uma seqüência de caracteres entre aspas, por
exemplo:
• "Linguagem de programação"
• "Qual é o seu nome?"
• "12345"
Dados Lógicos
Este tipo de dados é intensamente aplicado durante o processo de tomada de decisões que o
computador freqüentemente é obrigado a fazer. Em muitos textos este tipo de dados
também é chamado de dados booleanos, devido a George Boole, matemático que deu ao
nome à álgebra (álgebra booleana) que manipula este tipo de dados. Os dados deste tipo
somente podem assumir dois valores: verdadeiro e falso. Computadores tomam
decisões, durante o processamento de um algoritmo, baseados nestes dois valores. Por
exemplo, considere a decisão abaixo:
Se raiz >= 0 imprima "Existe raiz" caso contrário imprima "Não existe
raiz real."
Nesta instrução aparece a expressão raiz >= 0, que procura descobrir se o valor de raiz é
maior que 0. Esta expressão somente pode ter como resultado os valores: verdadeiro ou
falso. Nos nossos algoritmos estes valores serão representados por verdadeiro e falso.
Mais adiante ficará claro como este tipo de dados será empregado nos algoritmos.
Variáveis
São os nomes que utilizamos para referenciar as posições de memória. Como já foi
mostrado no capítulo de Introdução, a memória de um computador pode ser entendida
como um conjunto ordenado e numerado de palavras. Na maioria dos PCs que usamos
diariamente a memória pode ser considerada como um conjunto ordenado e numerado de
bytes (8 bits). As linguagens de programação de alto nível atribuem nomes as posições de
memória que armazenam os dados a serem processados. Deste modo os programadores tem
mais facilidade para construir seus algoritmos.
• i
• valor
• nome
• nota1
Na linguagem Visualg uma variável precisa ser definida antes de ser usada em um
algoritmo.
Expressões
Uma vez que já temos os dados e as variáveis podemos passar ao próximo estágio que seria
a criação de expressões. No entanto, para que a expressão possa estar completa precisamos
de operadores que possam ser aplicados a estes dados. Os operadores da linguagem Viaulg
são basicamente os mesmos encontrados em outras linguagens de programação.
• Expressões Aritméticas;
• Expressões Lógicas;
• Expressões Literais.
Expressões Aritméticas
Expressões aritméticas são aquelas que apresentam como resultado um valor numérico que
pode ser um número inteiro ou real, dependendo dos operandos e operadores. Os
operadores aritméticos disponíveis estão mostrados na tabela a seguir.
A prioridade indica a ordem em que cada operação deverá ser executada. Quanto menor o
número maior a prioridade da operação. Observe que o operador de multiplicação é o
caracter asterisco, um símbolo que é empregado na maioria das linguagens para esta
operação.
Expressões aritméticas podem manipular operandos de dois tipos: reais e inteiros. Se todos
os operandos de uma expressão são do tipo inteiro então a expressão fornece como
resultado um número inteiro. Caso pelo menos um dos operandos seja real o resultado será
real. Isto pode parecer estranho a princípio, mas este procedimento reflete a forma como as
operações são executadas pelos processadores. A seguir mostramos exemplos de algumas
expressões aritméticas:
• A+B-C
• a/b
• 3.14*(A+B)
Observar que as expressões somente podem ser escritas de forma linear, isto é o sinal de
divisão é uma barra inclinada. Portanto frações somente podem ser escritas conforme o
exemplo acima (a/b). Outro ponto importante é a ordem de avaliação das expressões, as
prioridades mostradas na Tabela dos operadores não é suficiente para resolver todas as
situações e precisamos apresentar algumas regras adicionais:
Vamos considerar alguns exemplos para mostrar como estas regras são aplicadas.
Considere as seguintes variáveis:
• A=2.0
• B=4.0
• C=1.0
1. A*B-C
2. A*(B-C)
3. B+A/C+5
4. (B+A)/(C+5)
A primeira expressão tem como resultado o valor 7, como era de se esperar. Na segunda
expressão a ordem de avaliação é alterada pelo parênteses e primeiro é feita a subtração e o
resultado passa ser 6. A primeira operação na terceira expressão é a divisão que tem maior
prioridade. Neste caso o resultado final é 11. Na última expressão as somas são realizadas
primeiro e por último a divisão, ficando o resultado igual a 1.
Expressões Lógicas
Expressões lógicas são aquelas cujo resultado pode somente assumir os valores
verdadeiro ou falso. Os operadores lógicos e sua ordem de precedência são mostrados na
Tabela a seguir.
Estes operadores e seus dados também possuem uma espécie de tabuada que mostra os
resultados de operações básicas. A Tabela a seguir mostra os resultados da aplicação destes
operadores à duas variáveis lógicas.
A B A ou B A e B não A
falso falso falso falso verdadeiro
falso verdadeiro verdadeiro falso verdadeiro
verdadeiro falso verdadeiro falso falso
verdadeiro verdadeiro verdadeiro verdadeiro falso
Há ainda um outro tipo de operadores que podem aparecer em expressões lógicas que são
os operadores relacionais. Estes operadores estão mostrados na Tabela a seguir.
Operador Descrição
> maior que
< menor que
>= maior ou igual a
<= menor ou igual a
= igual a
<> diferente de
• (A e B) ou C
• (A < 5) ou (b < 3)
Tratamento de caracteres
Comandos
Agora iremos apresentar uma série de definições informais dos comandos da linguagem a--.
• Lista de comandos:
<lista de comandos>
Uma seqüência de comandos válidos da linguagem. Em cada linha somente pode
haver um comando. Veremos que em alguns casos especiais um comando pode se
estender por mais de uma linha.
• Comando de atribuição:
<-
A expressão do lado direito do operador é calculada e o seu resultado é atribuído à
variável do lado esquerdo do sinal.
Exemplos:
a <- 5.0
b <- a + x - 3.0
Exemplo:
escreva("A media das notas foi", media, "nota 1", nota1, "nota 2",
nota2)
escreva("Entre com o salário." )
• Comando de repetição:
Exemplo:
I<-0
enquanto i<10 faça
escreva(i, i*i)
i<-i+1
fimenquanto
• Comando de teste (desvio)
Exemplo:
se (i % 2) = 0 entao
escreva("O número é par.")
senao
escreva("O número é ímpar.")
fimse
• Comentários
Exemplos de Algoritmos
1. Algoritmo de Euclides
Dados dois números positivos m e n encontre seu maior divisor comum, isto é o
maior inteiro positivo que divide tanto m como n. Assuma que m é sempre maior
que n, e n diferente de zero.
var
m,n,r:inteiro
inicio
leia(m, n)
r <- m % n // resto da divisão de m por n
enquanto r <> 0 faca
m <- n
n <- r
r <- m % n
fimenquanto
escreva(n)
fimalgoritmo