Você está na página 1de 129

ELEMENTOS DE ALGORITMIA

Introdução à Ciência dos Computadores


2006

Jorge Mota, Engº


Versão 6.5

Apontamentos para Apoio às aulas


Instituto Superior de Tecnologias Avançadas do Porto

Outubro/Novembro/Dezembro/Janeiro/Fevereiro de 2006/7
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Resumo

Saber e dominar a arte de criação e documentação algoritmica, no


contexto das competências de um engenheiro informático e/ou multimédia
é uma hoje em dia uma competência fundamental e essencial para todas as
outras valências da actividade de engenheiro.

Nesse contexto e como suporte às aulas da disciplina de Introdução à


Ciência dos Computadores, elaborei, compilei e anotei estes elementos que
não pretendem ser substituto da bibliografia recomendada, mas meros
elementos de apoio de leitura rápida.

Jorge Mota, 2006

2
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Abstract

To know and to master the art of algorithms and software Principes


creation and documentation, in the context of the abilities of an
IT/Multimedia engineer are nowadays a basic and essential competencie. In
this context and as a support to the lessons of disciplines of Introduction to
Computer Science of the ISTEC, I elaborated, compiled and I write down
these printed elements. This document doesn’t pretend to be a replacement
to the recomended bibliography, but only a rapid read complement.

Jorge Mota, 2006

3
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Conteúdo

Resumo................................................................................................ 2
Abstract ............................................................................................... 3
1 Noção de Algoritmo ....................................................................... 6
2 Fluxogramas .................................................................................. 7
3 Conceito de PseudoCódigo ou PseudoLinguagem .........................11
3.1 Forma geral de um algoritmo em pseudocódigo ............................................ 11
3.2 Entrada de dados............................................................................................. 15
3.3 Saída de dados ................................................................................................ 16
3.4 Estruturas de controlo de fluxo....................................................................... 17
3.5 Estruturas de sequência .................................................................................. 17
3.6 Estruturas de Decisão ..................................................................................... 18
3.7 Estruturas de Decisão Simples ....................................................................... 18
3.8 Estruturas de Decisão Múltipla ...................................................................... 19
3.9 Estruturas de Repetição ou Loop.................................................................... 20
3.10 Ciclos contados............................................................................................... 20
3.11 Ciclos Enquanto.............................................................................................. 21
3.12 Ciclos Repetir … Até que (cond) ................................................................... 22
4 Exemplos de documentação de algoritmos usando pseudocódigo 23
4.1 Primeiro exemplo ........................................................................................... 23
4.2 Outro exemplo de Algoritmo em pseudocódigo ............................................ 24
4.3 Exemplos de implementações em linguagens de programação...................... 24
4.4 O conceito de subprograma ............................................................................ 26
4.5 O Conceito de variavel Local e Global .......................................................... 27
4.6 Procedimentos ................................................................................................ 27
4.7 Funções........................................................................................................... 29
4.8 Passagem de parãmetros por referência.......................................................... 31
4.9 Recursividade ................................................................................................. 32
4.10 Tipos de dados Variaáveis e Expressões ........................................................ 32
4.11 Operadores Aritméticos.................................................................................. 33
4.12 Operadores relacionais ................................................................................... 34
4.13 Operadores Boleanos...................................................................................... 35
4.14 Ficheiros de Texto .......................................................................................... 35
5 Introdução a implementação de algoritmos usando linguagem C .37
5.1 Forma Geral de um programa em C ............................................................... 37
5.2 Declaração e inicialização de variaveis e constantes...................................... 37
5.3 Expressões em C............................................................................................. 37
5.4 Implementação de estruturas de controlo de fluxo......................................... 37
5.5 Leitura(input) e Escrita(output) de dados....................................................... 37
5.6 Funções, argumentos e passagem de parâmetros ........................................... 37
5.7 Exemplos de programas em C ........................................................................ 37
5.8 Arrays, Matrizes e Strings .............................................................................. 47
5.9 Ponteiros ......................................................................................................... 61

4
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

5.10 Estruturas avançadas de dados – Estruturas e uniões; Enumerações e tipos


definidos pelo utilizador ............................................................................................. 62
5.11 Ficheiros de Texto em C, Rapor e VisualAlg................................................. 62
6 Ordenação e Pesquisa...................................................................64
6.1 Pesquisa .......................................................................................................... 64
Pesquisa sequencial ou linear .............................................................65
Pesquisa binária .................................................................................65
6.2 Ordenação....................................................................................................... 71
7 Bubble sort ...................................................................................71
Ordenação por Selecção .....................................................................77
Insertion sort .....................................................................................80
Shell sort ............................................................................................83
Quicksort ............................................................................................87
Complexidade do Quicksort ....................................................................................... 87
7.1 Filas, Listas e Pilhas ....................................................................................... 94
8 Execicios de algoritmia com cálculo numérico ..............................95
9 Bibliografia .................................................................................129

5
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

1 Noção de Algoritmo

Um algoritmo é uma sequência não ambígua de instruções que é


executada até que determinada condição se verifique. Mais especificamente,
em matemática, constitui o conjunto de processos (e símbolos que os
representam) para efectuar um cálculo. Os Algoritmos podem ser
implementados por programas de computadores. A área que estuda os
algoritmos designa-se Ciências da Computação.

A palavra algoritmo tem origem no sobrenome, Al-Khwarizmi, do


matemático persa do século IX, Mohamed Ben Musa, cujas obras foram
traduzidas no ocidente cristão no século XII, tendo uma delas recebido o
nome "Algorithmi de numero indorum", que versa sobre os algoritmos,
usando o sistema de numeração decimal e indiano. Outros autores,
contudo, defendem a origem da palavra em Al-goreten (raiz - conceito que
se pode aplicar aos cálculos).

O conceito de algoritmo é freqüentemente ilustrado pelo exemplo de


uma receita, embora muitos algoritmos sejam mais complexos. Eles podem
repetir passos (fazer iterações) ou necessitar de decisões (tais como
comparações ou lógica) até que a tarefa seja completada. Um algoritmo
corretamente executado não irá resolver um problema se o algoritmo
estiver incorreto ou não for apropriado ao problema.

Um algoritmo não representa, necessariamente, um programa de


computador, e sim os passos necessários para realizar uma tarefa. Sua
implementação pode ser feita por um computador, por outro tipo de
autômato ou mesmo por um ser humano.
Diferentes algoritmos podem realizar a mesma tarefa usando um conjunto
diferenciado de instruções em mais ou menos tempo, espaço ou esforço do
que outros. Por exemplo, um algoritmo para se vestir pode especificar que
você vista primeiro as meias e os sapatos antes de vestir a calça enquanto
outro algoritmo especifica que você deve primeiro vestir a calça e depois as
meias e os sapatos. Fica claro que o primeiro algoritmo é mais difícil de
executar que o segundo.

6
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Um Fluxograma é um tipo de diagrama, e pode ser entendido como


uma representação esquemática de um processo, muitas vezes feita através
de gráficos que ilustram de forma descomplicada a transição de informações
entre os elementos que o compõem. Podemos entendê-lo, na prática, como
a documentação dos passos necessários para a execução de um processo
qualquer.

Um diagrama é uma representação visual estruturada e simplificada


de um determinado conceito, idéia.

2 Fluxogramas

Um fluxograma tipico, representado de forma tradicional, contém


normalmente os seguintes simbolos:

INICIO e FIM, representados por ovais ou rectangulos arrendondados,


normalmente contém as palavras Inicio e Fim e uma frase que descreve o
processo representado, como por exemplo calcular média de 10 numeros.

SETAS, mostrando o que designamos por “fluxo de controlo” em


ciência de computadores. Uma seta que vai de um simbolo para outro
respresenta que o controlo passa de um simbolo para outro.

Passos do PROCESSAMENTO, representados por rectangulos.


Exemplos: "Adicionar 1 a X"; "Guardar as alterações"; "a<-1+b" ou similar.

7
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Entrada/Saidas, representadas por paralelogramas. Exemplo LER X de


um teclado; ESCREVER X no ecrã.

ESTRUTURAS de DECISÃO, representadas como diamantes. Estas


representam tipicamente uma questão do tipo SIM/NÃO ou True/False.
Este simbolo apresenta duas setas de fluxo a sair do simbolo, um
correspondente a hipotese SIM outra à Não. Estas setas devem sempre
estar etiquetadas, para não levantar dúvidas.

8
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Uma forma compacta de representação de CICLOS contados pode ser


apresentado por um Hexagono. Este simbolo apresenta três setas de fluxo a
sair/entrada no mesmo. Uma para baixo que representa o corpo do ciclo,
uma seta a entrar pelo lado direito que representa o retorno a condição de
ciclo e finalmente um a sair do lado direito que é o fluxo executado quando
termina o ciclo. Todas as setas de fluxo devem estar convenienetemente
etiquetadas.

Os ciclos ou Loops são representados explicitamente por uma


condição, um corpo do ciclo e uma seta de fluxo que retorna ao inicio.
Quando esta à colocada à entrada, então estamos prerante um ciclo
ENQUANTO, o corpo do ciclo só é executado enquanto a condição é
verdadeira e se na primeira passagem a condição for falsa então o corpo do
ciclo nunca é executado. Se o teste (condição) é colocado no final do corpo
do ciclo então estamos perante um ciclo do tipo REPETIR …ATÉ QUE (cond),
que se carcteriza por ser executado enquanto a condição for falsa, e o corpo
do ciclo é sempre executado pelo menos uma vez.

Enquanto

Repetir até que (cond)

9
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Muitos outros simbolos, representando significados mais ou menos


universais podem ser usados de que destacamos :

Um Documento representado por um rectangulo com umabase


ondulada;

Um ficheiro/Base de Dados representado por um Cilindro

Os fluxogramas contêm ainda outros simbolos como Conectores intra


página e inter páginas (respectivamente representados por um circulo e um
rectangulo/seta). Dentro destes deve ser indicado uma letra ou numero que
faz a correspondência entre ligações.

10
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

3 Conceito de PseudoCódigo ou PseudoLinguagem

Pseudocódigo é uma forma genérica de escrever um algoritmo,


utilizando uma linguagem simples (nativa a quem o escreve, de forma a ser
entendido por qualquer pessoa) sem necessidade de conhecer a sintaxe de
nenhuma linguagem de programação. É, como o nome indica, um pseudo-
código e, portanto, não pode ser executado num sistema real (computador)
— de outra forma deixaria de ser pseudo.

Os livros sobre a ciência de computação utilizam frequentemente o


pseudocódigo para ilustrar os seus exemplos, de forma que todos os
programadores possam entendê-los (independentemente da linguagem que
utilizem).

Embora no caso da língua portuguesa existam alguns interpretadores


de pseudocódigo, nenhum tem a projecção das linguagens Pascal ou BASIC,
que no caso da língua inglesa se assemelham bastante a pseudo-código
(em inglês, claro).

3.1 Forma geral de um algoritmo em pseudocódigo

Introdução

Vamos usar como linguagem de represntação algoritmica o VisuAlg.


Esta interpretador é bem uma das muitas implementações disponiveis e
tem a vantagem de ser simples: é uma versão portuguesa dos
pseudocódigos largamente utilizados nos livros de introdução à
programação, conhecida como "Portugol". Tem comandos novos, com o
intuito de criar facilidades específicas para o ensino de técnicas de
elaboração de algoritmos.

A linguagem do VisuAlg permite apenas um comando por linha: desse


modo, não há necessidade de tokens separadores de estruturas, como o
ponto e vírgula em Pascal ou o ; em Linguagem C. Também não existe o
conceito de blocos de comandos (que correspondem ao begin e end do
Pascal e ao { e } do C), nem comandos de desvio incondicional como o

11
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

goto. Na versão actual do VisuAlg, com exceção das rotinas de entrada e


saída, não há nenhum subprograma embutido, tal como Inc(), Sqr(), Ord(),
Chr(), Pos(), Copy() ou outro.

Importante: para facilitar a digitação e evitar confusões, todas as


palavras-chave do VisuAlg foram implementadas sem acentos, cedilha, etc.
Portanto, o tipo de dados lógico é definido como logico, o comando
se..então..senão é definido como se..entao..senao, e assim por diante. O
VisuAlg também não distingue maiúsculas e minúsculas no reconhecimento
de palavras-chave e nomes de variáveis.

Formato Básico do Pseudocódigo e Inclusão de Comentários

O formato básico do nosso pseudocódigo é o seguinte:

algoritmo "semnome"
// Função :
// Autor :
// Data :
// Secção de Declarações
inicio
// Secção de Comandos
fimalgoritmo

A primeira linha é composta pela palavra-chave algoritmo seguida do


seu nome delimitado por aspas duplas. Este nome será usado como título
nas janelas de leitura de dados (nas futuras versões do VisuAlg, talvez
utilizemos este dado de outras formas). A secção que se segue é a de
declaração de variáveis, que termina com a linha que contém a palavra-
chave inicio. Deste ponto em diante está a secção de comandos, que
continua até a linha em que se encontre a palavra-chave fimalgoritmo. Esta
última linha marca o final do pseudocódigo: todo texto existente a partir
dela é ignorado pelo interpretador.

O VisuAlg permite a inclusão de comentários: qualquer texto


precedido de "//" é ignorado, até se atingir o final da sua linha. Por este
motivo, os comentários não se estendem por mais de uma linha: quando se

12
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

deseja escrever comentários mais longos, que ocupem várias linhas, cada
uma delas deverá começar por "//".

Tipos de Dados

Em algoritmia prevêmos quatro tipos de dados e am VisualAlg


também: inteiro, real, cadeia de caracteres e lógico (ou booleano). As
palavras-chave que os definem são as seguintes (observe que elas não têm
acentuação):

inteiro: define variáveis numéricas do tipo inteiro, ou seja, sem casas


decimais.

real: define variáveis numéricas do tipo real, ou seja, com casas


decimais.

caractere: define variáveis do tipo string, ou seja, cadeia de


caracteres.

logico: define variáveis do tipo booleano, ou seja, com valor


VERDADEIRO ou FALSO.

O VisuAlg permite também a declaração de variáveis estruturadas


através da palavra-chave vetor, como será explicado a seguir.

Nomes de Variáveis e sua Declaração

Os nomes das variáveis devem começar por uma letra e depois conter
letras, números ou underline, até um limite de 30 caracteres. As variáveis
podem ser simples ou estruturadas (na versão actual, os vetores podem ser
de uma ou duas dimensões). Não pode haver duas variáveis com o mesmo
nome, com a natural exceção dos elementos de um mesmo vetor.

A secção de declaração de variáveis começa com a palavra-chave var,


e continua com as seguintes sintaxes:

<lista-de-variáveis> : <tipo-de-dado>
<lista-de-variáveis> : vetor "["<lista-de-intervalos>"]" de <tipo-de-dado>

Na <lista-de-variáveis>, os nomes das variáveis estão separados por


vírgulas. Na <lista-de-intervalos>, os <intervalo> são separados por
vírgulas, e têm a seguinte sintaxe:

13
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

<intervalo>: <valor-inicial> .. <valor-final>

Na versão actual do VisuAlg, tanto <valor-inicial> como <valor-final>


devem ser inteiros. Além disso, exige-se evidentemente que <valor-final>
seja maior do que <valor-inicial>.

Exemplos:

var

a: inteiro
Valor1, Valor2: real
vet: vetor [1..10] de real
matriz: vetor [0..4,8..10] de inteiro
nome_do_aluno: caractere
sinalizador: logico

Note que não há a necessidade de ponto e vírgula após cada


declaração: basta pular linha. A declaração de vetores é análoga à
linguagem Pascal: a variável vet acima tem 10 elementos, com os índices
de [1] a [10], enquanto matriz corresponde a 15 elementos com índices
[0,8], [0,9], [0,10], [1,8], [1,9], [1,10], ... até [4,10]. O número total de
variáveis suportado pelo VisuAlg é 500 (cada elemento de um vetor é
contado individualmente).

Constantes e operação de Atribuição

Consideramos três tipos de constantes:

Numéricos: são valores numéricos escritos na forma usual das


linguagens de programação. Podem ser inteiros ou reais. Neste último caso,
o separador de decimais é o ponto e não a vírgula, independente da
configuração regional do computador onde o VisuAlg está sendo executado.
O VisuAlg também não suporta separadores de milhares.

Caracteres: qualquer cadeia de caracteres delimitada por aspas


duplas (").

Lógicos: admite os valores VERDADEIRO ou FALSO.

14
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

A atribuição de valores a variáveis é feita com o operador <-. Do seu


lado esquerdo fica a variável à qual está sendo atribuído o valor, e à sua
direita pode-se colocar qualquer expressão (constantes, variáveis,
expressões numéricas), desde que seu resultado tenha tipo igual ao da
variável.

Alguns exemplos de atribuições, usando as variáveis declaradas


acima:

a <- 3
Valor1 <- 1.5
Valor2 <- Valor1 + a
vet[1] <- vet[1] + (a * 3)
matriz[3,9] <- a/4 - 5
nome_do_aluno <- "José da Silva"
sinalizador <- FALSO

Na forma geral de um algoritmo encontramos três grandes conjuntos


de comandos(entrada de dados, saída de dados e estruturas de controlo de
fluxo):

3.2 Entrada de dados

leia (<lista-de-variáveis>)

Recebe valores digitados pelos utilizador, atribuindo-os às variáveis


cujos nomes estão em <lista-de-variáveis> (é respeitada a ordem
especificada nesta lista). É análogo ao comando read do Pascal e
semelhante ao Scanf() da linguagem C.

Veja no exemplo abaixo o resultado:

algoritmo "exemplo 1"


var x: inteiro;
inicio
leia (x)

15
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

escreva (x)
fimalgoritmo

3.3 Saída de dados

escreva (<lista-de-expressões>)

Escreve no dispositivo de saída standard. Em VisualAlg esta é, na


área à direita da metade inferior da tela, o conteúdo de cada uma das
expressões que compõem <lista-de-expressões>. As expressões dentro
desta lista devem estar separadas por vírgulas; depois de serem avaliadas,
seus resultados são impressos na ordem indicada. É equivalente ao
comando write do Pascal ou printf() da linguagem C.

De modo semelhante ao C com a “string” de controlo, é possível


especificar o número de espaços no qual se deseja escrever um
determinado valor. Por exemplo, o comando escreva(x:5) escreve o valor
da variável x em 5 espaços, alinhado-o à direita. Para variáveis reais, pode-
se também especificar o número de casas fracionárias que serão exibidas.
Por exemplo, considerando y como uma variável real, o comando
escreva(y:6:2)escreve seu valor em 6 espaços colocando 2 casas decimais.

escreval (<lista-de-expressões>).

Idêntico ao anterior, com a única diferença que salta uma linha. É


equivalente ao writeln do Pascal ou scanf() com string de controlo que
comtemple \n (line feed).

Exemplos:

algoritmo "exemplo"
var x: real
y: inteiro
a: caractere
l: logico
inicio
x <- 2.5
y <- 6

16
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

a <- "teste"
l <- VERDADEIRO
escreval ("x", x:4:1, y+3:4) // Escreve: x 2.5 9
escreval (a, "ok") // Escreve: testeok (e depois pula linha)
escreval (a, " ok") // Escreve: teste ok (e depois pula linha)
escreval (a + " ok") // Escreve: teste ok (e depois pula linha)
escreva (l) // Escreve: VERDADEIRO
fimalgoritmo

Note que o VisuAlg separa expressões do tipo numérico e lógico com


um espaço à esquerda, mas não as expressões do tipo caractere, para que
assim possa haver a concatenação. Quando se deseja separar expressões
do tipo caractere, é necessário acrescentar espaços nos locais adequados.

"Entre com o valor de <nome-de-variável>"

3.4 Estruturas de controlo de fluxo

Como se repreentam as principais estruturas de controlo de fluxo,


entrada e saida de dados, comentários e declaração de variaveis em
pesudocódigo (vamos usar a notação do Visualalg).

3.5 Estruturas de sequência

Em Pseudocódigo vamos adoptar uma notação próxima do Pascal em


que a marcação do inicio e fim dos blocos são expressos pelo inicio e fim da
estrutura de controlo, declaração ou subprograma.

Exemplo:

inicio

A<-1+b

Escrevel(a)

Fimalgoritmo

17
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

3.6 Estruturas de Decisão

As estruturas de decisão são muito importantes em algoritmia e


programação. Na realidade podemos dizer que é com estas que
conseguimos implementar regras que tornam os nossos programas
“inteligentes”. Conseideramos dois tipos de estruturas de decisão
(condicionais) as de decisão simples e Múltipla.

3.7 Estruturas de Decisão Simples

se <expressão-lógica> entao
<seqüência-de-comandos>
fimse

Ao encontrar este comando, o VisuAlg analisa a <expressão-lógica>.


Se o seu resultado for VERDADEIRO, todos os comandos da <seqüência-de-
comandos> (entre esta linha e a linha com fimse) são executados. Se o
resultado for FALSO, estes comandos são desprezados e a execução do
algoritmo continua a partir da primeira linha depois do fimse.

se <expressão-lógica> entao
<seqüência-de-comandos-1>
senao
<seqüência-de-comandos-2>
fimse

Nesta outra forma do comando, se o resultado da avaliação de


<expressão-lógica> for VERDADEIRO, todos os comandos da <seqüência-
de-comandos-1> (entre esta linha e a linha com senao) são executados, e a
execução continua depois a partir da primeira linha depois do fimse. Se o
resultado for FALSO, estes comandos são desprezados e o algoritmo
continua a ser executado a partir da primeira linha depois do senao,
executando todos os comandos da <seqüência-de-comandos-2> (até a
linha com fimse).

Estes comandos equivalem ao if...then e if...then...else do Pascal.


Note que não há necessidade de delimitadores de bloco (como begin e end),

18
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

pois as seqüências de comandos já estão delimitadas pelas palavras-chave


senao e fimse. O VisuAlg permite o aninhamento desses comandos de
desvio condicional.
3.8 Estruturas de Decisão Múltipla

O VisuAlg implementa (com certas variações) o comando case do


Pascal ( ou switch da linguagem C). A sintaxe é a seguinte:

escolha <expressão-de-seleção>
caso <exp11>, <exp12>, ..., <exp1n>
<seqüência-de-comandos-1>
caso <exp21>, <exp22>, ..., <exp2n>
<seqüência-de-comandos-2>
...
outrocaso
<seqüência-de-comandos-extra>
fimescolha

Veja o exemplo a seguir, que ilustra bem o que faz este comando:

algoritmo "Times"
var time: caractere
inicio
escreva ("Entre com o nome de um time de futebol: ")
leia (time)
escolha time
caso "Flamengo", "Fluminense", "Vasco", "Botafogo"
escreval ("É um time carioca.")
caso "São Paulo", "Palmeiras", "Santos", "Corínthians"
escreval ("É um time paulista.")
outrocaso
escreval ("É de outro estado.")
fimescolha
fimalgoritmo

19
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

3.9 Estruturas de Repetição ou Loop

Em ciência dos Computadores e Algoritmia usamos três estruturas de


repetição comuns nos algoritmos: o ciclo contado para...ate...faca (similar
ao for...to...do do Pascal ou for(;;) do C), e os ciclos condicionados
enquanto...faca (similar ao while...do ou While {} do C) e repita...ate
(similar ao repeat...until ou repit …until cond do C). A sintaxe destas
estruturas de controlo de fluxo é explicada a seguir:

3.10 Ciclos contados

Para ... faça

Esta estrutura repete uma seqüência de comandos um determinado número


de vezes.

para <variável> de <valor-inicial> ate <valor-limite> [passo


<incremento>] faca
<seqüência-de-comandos>
fimpara

É a variável contadora que controla o número de


repetições do ciclo. Na versão actual, deve ser
<variável >
necessariamente uma variável do tipo inteiro, como todas
as expressões deste comando.
É uma expressão que especifica o valor de inicialização da
<valor-inicial>
variável contadora antes da primeira repetição do ciclo.
É uma expressão que especifica o valor máximo que a
<valor-limite >
variável contadora pode alcançar.
É opcional. Quando presente, precedida pela palavra
passo, é uma expressão que especifica o incremento que
será acrescentado à variável contadora em cada repetição
do ciclo. Quando esta opção não é utilizada, o valor
padrão de <incremento> é 1. Vale a pena ter em conta
<incremento >
que também é possível especificar valores negativos para
<incremento>. Por outro lado, se a avaliação da
expressão <incremento > resultar em valor nulo, a
execução do algoritmo será interrompida, com a
impressão de uma mensagem de erro.
Indica o fim da seqüência de comandos a serem
repetidos. Cada vez que o programa chega neste ponto, é
fimpara
acrescentado à variável contadora o valor de <incremento
>, e comparado a <valor-limite >. Se for menor ou igual

20
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

(ou maior ou igual, quando <incremento > for negativo),


a seqüência de comandos será executada mais uma vez;
caso contrário, a execução prosseguirá a partir do
primeiro comando que esteja após o fimpara.

<valor-inicial >, <valor-limite > e <incremento > são avaliados uma única
vez antes da execução da primeira repetição, e não se alteram durante a
execução do ciclo, mesmo que variáveis eventualmente presentes nessas
expressões tenham seus valores alterados.

No exemplo a seguir, os números de 1 a 10 são exibidos em ordem


crescente.

algoritmo "Números de 1 a 10"


var j: inteiro
inicio
para j de 1 ate 10 faca
escreva (j:3)
fimpara
fimalgoritmo

Importante: Se, logo no início da primeira repetição, <valor-inicial > for


maior que <valor-limite > (ou menor, quando <incremento> for negativo),
o ciclo não será executado nenhuma vez. O exemplo a seguir não imprime
nada.

algoritmo "Numeros de 10 a 1 (não funciona)"


var j: inteiro
inicio
para j de 10 ate 1 faca
escreva (j:3)
fimpara
fimalgoritmo

Este outro exempo, no entanto, funcionará por causa do passo -1:

algoritmo "Numeros de 10 a 1 (este funciona)"


var j: inteiro
inicio
para j de 10 ate 1 passo -1 faca
escreva (j:3)
fimpara
fimalgoritmo

3.11 Ciclos Enquanto

Enquanto ... faça

21
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Esta estrutura repete uma seqüência de comandos enquanto uma


determinada condição (especificada através de uma expressão lógica) for
satisfeita.

enquanto <expressão-lógica> faca


<seqüência-de-comandos>
fimenquanto

Esta expressão que é avaliada antes de cada repetição


<expressão-lógica> do ciclo. Quando seu resultado for VERDADEIRO,
<seqüência-de-comandos> é executada.

Indica o fim da <seqüência-de-comandos> que será


repetida. Cada vez que a execução atinge este ponto,
volta-se ao início do ciclo para que <expressão-
lógica> seja avaliada novamente. Se o resultado
fimenquanto
desta avaliação for VERDADEIRO, a <seqüência-de-
comandos> será executada mais uma vez; caso
contrário, a execução prosseguirá a partir do primeiro
comando após fimenquanto.

O mesmo exemplo anterior pode ser resolvido com esta estrutura de


repetição:

algoritmo "Números de 1 a 10 (com enquanto...faca)"


var j: inteiro
inicio
j <- 1
enquanto j <= 10 faca
escreva (j:3)
j <- j + 1
fimenquanto
fimalgoritmo

Importante: Como o ciclo enquanto...faca testa sua condição de parada


antes de executar sua seqüência de comandos, esta seqüência poderá ser
executada zero ou mais vezes.

3.12 Ciclos Repetir … Até que (cond)

Esta estrutrura repete uma seqüência de comandos até que uma


determinada condição (especificada através de uma expressão lógica) seja
satisfeita.

22
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

repita
<seqüência-de-comandos>
ate <expressão-lógica>

repita Indica o início do ciclo.

Indica o fim da <seqüência-de-comandos> a serem


repetidos. Cada vez que o programa chega neste ponto,
<expressão-lógica> é avaliada: se seu resultado for
ate <expressão-
FALSO, os comandos presentes entre esta linha e a linha
lógica>
repita são executados; caso contrário, a execução
prosseguirá a partir do primeiro comando após esta
linha.

Considerando ainda o mesmo exemplo:

algoritmo "Números de 1 a 10 (com repita)"


var j: inteiro
inicio
j <- 1
repita
escreva (j:3)
j <- j + 1
ate j > 10
fimalgoritmo

4 Exemplos de documentação de algoritmos usando


pseudocódigo

4.1 Primeiro exemplo

Abaixo fica o exemplo de um programa que faz a leitura de 10 números e


calcula uma média de apenas numeros positivos.

S <- 0;
C <- 0;
PARA i<- 1 ATÉ 10 FAZ

23
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

LER (a);
SE a >=0 ENTÃO
S <- S+a
C <- C+1
FIM SE;
FIM PARA;
MD <- S/C
ESCREVER ("A média é:", MD)

4.2 Outro exemplo de Algoritmo em pseudocódigo

Exemplo de um algoritmo que irá retornar a soma de dois valores (também


conhecidos como parâmetros ou argumentos) que são introduzidos na
chamada da função:

função SomaDeDoisValores (A numérico, B numérico)


inicio
declare SOMA numérico
SOMA <-- A + B
retorne (SOMA)
fim

4.3 Exemplos de implementações em linguagens de programação

4.3.1 Action Script


function somaDeDoisValores (a, b)
{
trace(a + b)
};

4.3.2 C/C++/Java/C#/D
public int SomaDeDoisValores (int a, int b) {
return a + b;
}

4.3.3 Cobol
compute c = a + b.

4.3.4 Delphi
function SomaDeDoisValores( A, B: Integer ): Integer;
begin
Result := A + B;
end;

24
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

4.3.5 Haskell
soma :: Integer -> Integer -> Integer -- (assinatura)
soma a b = a + b

A assinatura da função pode ser dispensada, mas normalmente é colocada


no código por motivo de clareza.

4.3.6 JavaScript
function SomaDeDoisValores(val1, val2)
{
return (parseInt(val1) + parseInt(val2));
}

Seguindo padrões de programação, usa-se a primeira letra maiúscula


apenas em classes; em funções usa-se a primeira letra minúscula.

4.3.7 Logo
defina SomaDeDoisValores [[a b]] [escreva soma :a :b]]

4.3.8 Pascal
function SomaDeDoisValoresInteiros( A, B: Integer ): Integer;
begin
Result := A + B;
end;

4.3.9 Perl
sub SomaDeDoisValores {
my ($int1,$int2) = @_;
return $int1 + $int2;
}

4.3.10 PHP
function SomaDeDoisValores($VlrA, $VlrB)
{
return ($VlrA + $VlrB);
}

4.3.11 Prolog
somaDeDoisValores(A,B,Result):- Result is A+B.

4.3.12 Python
def SomaDeDoisValores (a, b):
return a + b

4.3.13 Ruby
def soma_de_dois_valores(a, b)
a+b

25
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

end

4.3.14 Scheme
(define Soma (lambda (x y) (x + y)) )

4.3.15 VBScript
function SomaDeDoisValores (a,b)
SomaDeDoisValores=a+b
end function

4.3.16 Visual Basic


function SomaDeDoisValores(byval a as integer, byval b as integer) as
integer
SomaDeDoisValores = a + b
end function

4.4 O conceito de subprograma

Subprograma é um programa. Deve corresponder a unidade atomica


de implementação algoritmica, resultado da simplificação de problemas pelo
método TOP-DOWN, ou seja à decomposição em problemas
sucessivamente mais simples, até que seja implementavel fácilmente e
suficientemente genérico para permitir a sua reutilização. Também costuma
receber os nomes de sub-rotina, procedimento, método, Função ou módulo.
Os subprogramas são chamados dentro do corpo do programa principal
como se fossem comandos/expressão. Após seu término, a execução
continua a partir do ponto onde foi chamado. É importante compreender
que a chamada de um subprograma simplesmente gera um desvio
provisório no fluxo de execução.

Há um caso particular de subprograma que recebe o nome de função.


Uma função, além de executar uma determinada tarefa, retorna um valor
para quem a chamou, que é o resultado da sua execução. Por este motivo,
a chamada de uma função aparece no corpo do programa principal como
uma expressão, e não como um comando.

26
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Em Fluxogramas representamos a chamada a um subprograma pelo


simbolo:

4.5 O Conceito de variavel Local e Global

Cada subprograma, além de ter acesso às variáveis do programa que


o chamou (são as variáveis globais), pode ter suas próprias variáveis (são
as variáveis locais), que existem apenas durante sua chamada.

Ao se chamar um subprograma, também é possível passar-lhe


determinadas informações que recebem o nome de parâmetros (são valores
que, na linha de chamada, ficam entre os parênteses e que estão separados
por vírgulas). A quantidade dos parâmetros, sua seqüência e respectivos
tipos não podem mudar: devem estar de acordo com o que foi especificado
na sua correspondente declaração.

Para se criar subprogramas, é preciso descrevê-los após a declaração


das variáveis e antes do corpo do programa principal.
4.6 Procedimentos

Na ferramenta VisuAlg (representação em pseudocódigo),


procedimento é um subprograma que não retorna nenhum valor
(corresponde a uma função que não devolve valores (void) em linguagem C
ou ao procedure do Pascal). Sua declaração, que deve estar entre o final da
declaração de variáveis e a linha inicio do programa principal, segue a
sintaxe abaixo:

procedimento <nome-de-procedimento> [(<seqüência-de-


declarações-de-parâmetros>)]
// Secção de Declarações Internas

27
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

inicio
// Secção de Comandos
fimprocedimento

O <nome-de-procedimento> obedece as mesmas regras de


nomenclatura das variáveis. Por outro lado, a <seqüência-de-declarações-
de-parâmetros> é uma seqüência de

[var] <seqüência-de-parâmetros>: <tipo-de-dado>

separadas por ponto e vírgula. A presença (opcional) da palavra-chave


var indica passagem de parâmetros por referência; caso contrário, a
passagem será por valor.

Por sua vez, <seqüência-de-parâmetros> é uma seqüência de nomes


de parâmetros (também obedecem a mesma regra de nomenclatura de
variáveis) separados por vírgulas.

De modo análogo ao programa principal, a secção de declaração


internas começa com a palavra-chave var, e continua com a seguinte
sintaxe:

<lista-de-variáveis> : <tipo-de-dado>

Nos próximos exemplos, através de um subprograma soma, será


calculada a soma entre os valores 4 e –9 (ou seja, será obtido o resultado
13) que o programa principal imprimirá em seguida. No primeiro caso, um
procedimento sem parâmetros utiliza uma variável local aux para
armazenar provisoriamente o resultado deste cálculo (evidentemente, esta
variável é desnecessária, mas está aí apenas para ilustrar o exemplo),
antes de atribuí-lo à variável global res:

procedimento soma
var aux: inteiro
inicio
// n, m e res são variáveis globais
aux <- n + m
res <- aux
fimprocedimento

28
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

No programa principal deve haver os seguintes comandos:


n <- 4
m <- -9
soma
escreva(res)

A mesma tarefa poderia ser executada através de um procedimento


com parâmetros, como descrito abaixo:

procedimento soma (x,y: inteiro)


inicio
// res é variável global
res <- x + y
fimprocedimento

No programa principal deve haver os seguintes comandos:


n <- 4
m <- -9
soma(n,m)
escreva(res)

A passagem de parâmetros do exemplo acima chama-se passagem


por valor. Neste caso, o subprograma simplesmente recebe um valor que
utiliza durante sua execução. Durante essa execução, os parâmetros
passados por valor são análogos às suas variáveis locais, mas com uma
única diferença: receberam um valor inicial no momento em que o
subprograma foi chamado.

4.7 Funções

A função é um subprograma que retorna um valor (corresponde ao


function da linguagem C). Na ferramenta VisualAlg e de modo análogo aos
procedimentos, sua declaração deve estar entre o final da declaração de
variáveis e a linha inicio do programa principal, e segue a sintaxe abaixo:

29
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

funcao <nome-de-função> [(<seqüência-de-declarações-de-


parâmetros>)]: <tipo-de-dado>
// Secção de Declarações Internas
inicio
// Secção de Comandos
fimfuncao

O <nome-de-função> obedece as mesmas regras de nomenclatura


das variáveis. Por outro lado, a <seqüência-de-declarações-de-parâmetros>
é uma seqüência de

[var] <seqüência-de-parâmetros>: <tipo-de-dado>

separadas por ponto e vírgula. A presença (opcional) da palavra-chave


var indica passagem de parâmetros por referência; caso contrário, a
passagem será por valor.

Por sua vez, <seqüência-de-parâmetros> é uma seqüência de nomes


de parâmetros (também obedecem a mesma regra de nomenclatura de
variáveis) separados por vírgulas.

O valor retornado pela função será do tipo especificado na sua


declaração (logo após os dois pontos). Em alguma parte da função (de
modo geral, no seu final), este valor deve ser retornado através do
comando retorne.

De modo análogo ao programa principal, a secção de declaração


internas começa com a palavra-chave var, e continua com a seguinte
sintaxe:

<lista-de-variáveis> : <tipo-de-dado>

Voltando ao exemplo anterior, no qual calculamos e imprimimos a


soma entre os valores 4 e –9, vamos mostrar como isso poderia ser feito
através de uma função sem parâmetros. Ela também utiliza uma variável
local aux para armazenar provisoriamente o resultado deste cálculo, antes
de atribuí-lo à variável global res:

funcao soma: inteiro


var aux: inteiro

30
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

inicio
// n, m e res são variáveis globais
aux <- n + m
retorne aux
fimfuncao

No programa principal deve haver os seguintes comandos:


n <- 4
m <- -9
res <- soma
escreva(res)

Se realizássemos essa mesma tarefa com uma função com


parâmetros passados por valor, poderia ser do seguinte modo:

funcao soma (x,y: inteiro): inteiro


inicio
retorne x + y
fimfuncao

No programa principal deve haver os seguintes comandos:


n <- 4
m <- -9
res <- soma(n,m)
escreva(res)

4.8 Passagem de parãmetros por referência

Há ainda uma outra forma de passagem de parâmetros para


subprogramas: é a passagem por referência. Neste caso, o subprograma
não recebe apenas um valor, mas sim o endereço de uma variável global.
Portanto, qualquer modificação que for realizada no conteúdo deste
parâmetro afetará também a variável global que está associada a ele.
Durante a execução do subprograma, os parâmetros passados por
referência são análogos às variáveis globais. Na ferramenta

31
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

VisuAlg(pseudocódigo), de forma análoga a Pascal, essa passagem é feita


através da palavra var na declaração do parâmetro.

Voltando ao exemplo da soma, o procedimento abaixo realiza a


mesma tarefa utilizando passagem de parâmetros por referência:

procedimento soma (x,y: inteiro; var result: inteiro)


inicio
result <- x + y
fimprocedimento

No programa principal deve haver os seguintes comandos:


n <- 4
m <- -9
soma(n,m,res)
escreva(res)

4.9 Recursividade

Recursividade é a possibilidade de que um subprograma se possa


chamar a si mesmo. A função apresentada abaixo calcula recursivamente o
factorial do número inteiro que recebe como parâmetro:

funcao factorial (v: inteiro): inteiro


inicio
se v <= 2 entao
retorne v
senao
retorne v * fatorial(v-1)
fimse
fimfuncao

4.10 Tipos de dados Variaáveis e Expressões

32
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Tipos de dados primitivos mais comuns em algoritmia (ciência dos


computadores):

Real (Numero do Tipo 3.1416)


inteiro(Numero do Tipo 23)

Caractere (Caracter do Tipo “a” ou “1”)


logico (Tipo falso ou verdadeiro)

Em pesudocódigo declaramos explicitamente os tipos na declaração


das variaveis e constantes na seccção Var.

Exemplo:

var x: real
y: inteiro
a: caractere
l: logico

Em linguagem C temos diferentes Classes, classificadores e operações


de casting de tipos, para alterar os tipos base enunciados. Assim por
exemplo atributos como register, volatil, signed, extern, static, long e
outros podem alterar significativamente os intervalos de valores
respresentaveis pelos diversos tipos base.
4.11 Operadores Aritméticos

Operadores unários, isto é, são aplicados a um único


operando. São os operadores aritméticos de maior precedência.
+,- Exemplos: -3, +x. Enquanto o operador unário - inverte o sinal do
seu operando, o operador + não altera o valor em nada o seu
valor.

Operador de divisão inteira. Por exemplo, 5 \ 2 = 2. Tem a


\
mesma precedência do operador de divisão tradicional.

33
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Operadores aritméticos tradicionais de adição, subtração,


multiplicação e divisão. Por convenção, * e / têm precedência
+,-,*,/ sobre + e -. Para modificar a ordem de avaliação das operações, é
necessário usar parênteses como em qualquer expressão
aritmética.

Operador de módulo (isto é, resto da divisão inteira). Por


% exemplo, 8 % 3 = 2. Tem a mesma precedência do operador de
divisão tradicional.

Operador de potenciação. Por exemplo, 5 ^ 2 = 25. Tem a


^ maior precedência entre os operadores aritméticos binários
(aqueles que têm dois operandos).

Operadores Unários formalmente equivalente ao incremento


ou decremento de uma unidade.Exemplo em linguagem C: ++a é
equialente a a=a+1 (semelhante para o operador --). Lembra-se
no entanto que ++a e a++ t~em comportamentos diferentes
++ , --
numa operação de atribuição. Exemplo: b=++a é diferente de
B=a++.No primeiro caso primeiro a variavel a é incrementada e
só depois atribuida a b, no segundo caso primeiro é feito a
atribuição e só depois é feito o incremento.

Operadores de Caracteres

Operador de concatenação de strings (isto é, cadeias de


caracteres), em peseudo código mas com implementação em
linguagens de programação muito distintas. Quando usado com dois
+
valores (variáveis ou constantes) do tipo "caractere" em
pseudocódigo o seu comportamento é conforme representado no
exemplo: "Rio " + " de Janeiro" = "Rio de Janeiro".

4.12 Operadores relacionais

34
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Respectivamente: igual, menor que, maior que, menor ou igual a,


=, <,
maior ou igual a, diferente de. São utilizados em expressões lógicas
>,
para se testar a relação entre dois valores do mesmo tipo. Exemplos:
<=,
3 = 3 ( 3 é igual a 3?) resulta em VERDADEIRO ; "A" > "B" ("A" está
>=,
depois de "B" na ordem alfabética?) resulta em FALSO. Lembra-se
<>
que em linguagem C o operador <> é impementado como !=.
4.13 Operadores Boleanos

Operador unário de negação. nao VERDADEIRO = FALSO, e nao


FALSO = VERDADEIRO. Tem a maior precedência entre os
nao
operadores lógicos. Equivale ao NOT do Pascal ou ao ! da linguagem
C.
Operador que resulta VERDADEIRO quando um dos seus operandos
ou lógicos for verdadeiro. Equivale ao OR do Pascal ou || da linguagem
C.
Operador que resulta VERDADEIRO somente se seus dois operandos
e lógicos forem verdadeiros. Equivale ao AND do Pascal ou ao && da
Linguagem C.
Operador que resulta VERDADEIRO se seus dois operandos lógicos
Xou forem diferentes, e FALSO se forem iguais. Equivale ao XOR do Pascal
e não existe explicitamente em linguagem C.

4.14 Ficheiros de Texto

Uma forma muito comum de armazenamento ou leitura de dados é o


ficheiro de texto. Essencialmente usamos dois tipos de estrutura de
ficheiros de textoquanto ao tipo de acesso:

Os ficheiros SEQUÊNCIAIS

Os ficheiros ALEATÓRIOS ou RANDÔMICOS

Esta classificação deriva do facto do acesso nos primeiros ter que ser
feita sequêncialmente, e no segundo poder ser feita de forma aleatória.
Lembro no entanto que para este segundo tipo de organização os registos
do ficheiro são de dimensão fixa.

Comando Arquivo

Em pseudocódigo vamos utilizar o termo arquivo ou ficheiro como


sinônimos mas em VisualAlg será utilizado o termo arquivo. O VisuAlg

35
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

permite o armazenamento de dados em um arquivo-texto, obtendo deles os


dados ao através dos comandos leia.
Esta característica funciona da seguinte maneira:
1) Se não existir o arquivo com nome especificado, o VisuAlg fará uma
leitura de dados através da digitação, armazenando os dados lidos neste
arquivo, na ordem em que forem fornecidos.
2) Se o arquivo existir, o VisuAlg obterá os dados deste arquivo até
chegar ao seu fim. Daí em diante, fará as leituras de dados através da
digitação.
3) Somente um comando arquivo pode ser empregado em cada
pseudocódigo, e ele deverá estar na seção de declarações (dependendo do
"sucesso" desta característica, em futuras versões ela poderá ser
melhorada...).
4) Caso não seja fornecido um caminho, o VisuAlg irá procurar este
arquivo na pasta de trabalho corrente (geralmente, é a pasta onde o
programa VISUALG.EXE está). Este comando não prevê uma extensão
padrão; portanto, a especificação do nome do arquivo deve ser completa,
inclusive com sua extensão (por exemplo, .txt, .dat, etc.).

A sintaxe do comando é:

arquivo <nome-de-arquivo>

<nome-de-arquivo> é uma constante caractere (entre aspas duplas).


Veja o exemplo a seguir:

algoritmo "lendo do arquivo"


arquivo "teste.txt"
var x,y: inteiro
inicio
para x de 1 ate 5 faca
leia (y)
fimpara
fimalgoritmo

36
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

5 Introdução a implementação de algoritmos usando


linguagem C (a implementar na disciplina de Programação I)

5.1 Forma Geral de um programa em C


5.2 Declaração e inicialização de variaveis e constantes
5.3 Expressões em C
5.4 Implementação de estruturas de controlo de fluxo
5.5 Leitura(input) e Escrita(output) de dados
5.6 Funções, argumentos e passagem de parâmetros

5.7 Exemplos de programas em C

Vamos implementar exemplos muito simples em linguagem C para


compreender todo o ciclo de desenvolvimento de um algoritmo e a sua
implmentação numa linguagem de alto nível, a linguagem C. Para o efeito
vamos usar um compilador rudimentar o Pacific C 7.51 da Hitec para Ms-
Dos (Lembram-se !!!). Este compilador possui um interface em DOS
rudimentar que inclui um editor com capacidade de salientar
contextualmente as palavras e funções standards do C. Todo o ciclo de
compilação é executado neste ambiente:

37
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Os passos necessários a compilação de um programa executavel são:

1. Fazer um duplo click no simbolo do Editor do Compilador


PPD.EXE

2. Criar o programa em Linguagem C no editor. Salvar o programa


em directoria(pasta) apropriada.

3. Executar a compilação e linkagem, usando a opção


Compile/Compile and Link. Nesta fase o compilador verifica se
existem erros e assinala-os na janela inferior. Se occorrem
erros não é criado nenhum executavel capaz de correr em
Windows.

4. Correr o programa executando Run/Run Nome do programa

Exemplo 1 – Calcular a média de uma lista de 10 notas(inteiros)


resultantes de um teste numa turma.

PseudoCódigo em VisualAlg 2.0

algoritmo "Media_notas"

// Função : Calcular a media das notas de uma disciplina

// Autor : Jorge Mota

// Data : 08-11-2006

// Vamos cacular a media pela formula Media=Somatorio_notas/Numero de Notas

//Versão 1.0

var

i,n:inteiro

soma,media,nota:real

inicio

//inicialização de variaveis

Soma<-0

media<-0

nota<-0

i<-0

n<-0

38
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

// ler o numero de alunos dos quais se pretende ler notas

escreval("Numero de notas que quer ler :")

leia(n)

//Ciclo em que vamos ler a nota de cada aluno e a acumulamos em SOMA

para i<-1 ate n faca

escreva("Nota ")

escreval(i)

leia(nota)

soma<-soma+nota

fimpara

media<-soma/n

escreva("A Média da Turma é =")

escreval(media)

fimalgoritmo

Fluxograma (Visio)

Implementação em Linguagem C

Exemplo 2 – Calcular e imprimir os numeros primos até 100.

PseudoCódigo em VisualAlg 2.0

Fluxograma (Visio)

Implementação em Linguagem C

Exemplo 3 – Calcular e imprimir a tabuada dos 5.

PseudoCódigo em VisualAlg 2.0

Fluxograma (Visio)

39
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação em Linguagem C

Exemplo 4 – Calcular o factorial de um número.

PseudoCódigo em VisualAlg 2.0

algoritmo "Calcular_o_factorial_de_10"
// Função : Calcula o factorial de 10 usando
//uma função generica factorial()
// Autor : Jorge Mota
// Data : 21-11-2006
// VERSÃO 1.0
var
Valor:inteiro
inicio
funcao factorial(n:inteiro):inteiro
var
i,f:inteiro
inicio
f<-1
para i<-n ate 1 passo -1 faca
f<-f*i
fimpara
retorne f
fimfuncao
// Indicar o numero a calcula
valor<-factorial(10)
escreval("O factorial de 10=",valor)
fimalgoritmo

Fluxograma (Visio)

40
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação em Linguagem C

#include "stdio.h"
int factorial(int n);
main()
{
int valor;
valor=factorial(10);
printf("O factorial de 10=%d\n",valor);
}
int factorial(int n)
{
int i,f;
f=1;
for(i=n;i>=1;--i)
{
f=f*i;
}
return f;
}

41
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Exemplo 5 – Calcular as raizes de uma equação do 2º Grau


Ax^2+Bx+C=0, e imprimir o resultado na forma :X1=a+|b|.

PseudoCódigo em VisualAlg 2.0

algoritmo "Calculo das Raizes de uma Equação do 2 grau"

// Função : Calcular pela formula resolvente as raizes reais se // A==0

// Neste caso usar a formula X1R<-((-b+sqrt(Delta))/(2*a))

// X2R<-((-b+sqrt(Delta))/(2*a))

// X1i<-0 e X2i<-0

// CASO DELTA SEJA MENOR QUE 0 ENTÃO

// x1r<-(-b)/(2*a)

// x1i<- SQRT(-DELTA)/(2*A)

// x2r<-x1r

// x2i<--x1i

// em ambos os casos delta<-b^2-4*a*c

// Autor : Jorge Mota

// Data : 28-11-2006

// Secção de Declarações de variaveis

// A,B,C,Delta,x1r,x2r,x1i,x2i como numeros reais

// temos que assegurar que a!=0

var

A,B,C,Delta,x1r,x2r,x1i,x2i real;

inicio

// Secção de Comandos

// Leitura de A,B,C

// A leitura de A tem que ser !=0

repita

escreva("A=")

leia(A)

fimrepita (A<>0)

//ler b

escreva ("B=")

leia(B)

42
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

//Ler C

escreva("C=")

leia(C)

//Calcular o Delta

delta<-b^2-4*a*c

SE (delta>=0) entao

x1r<-((-b)+SRQT(delta))/(2*a)

x2r<-((-b)-SRQT(delta))/(2*a)

x1i<-0

x2i<-0

senao

x1r<-(-b)/(2*a)

x1i<-SQRT(-delta)/(2*a)

x2r<-x1r

x2i<-(-x1i)

fimse

//Escrever em formato numeros complexos

escreva("X1=")

escreva(x1r)

escreva("+i")

escreval(x1i)

//Escrever em formato numeros complexos

escreva("X2=")

escreva(x2r)

escreva("+i")

escreval(x2i)

//Termina

fimalgoritmo

Fluxograma (Visio)

43
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação em Linguagem C

#include <stdio.h>
#include <math.h>

void main(void)
{
/*Calculo das raizes de uma equacao do 2 Grau
Jorge Mota
V1.0
28-11-06
IMPORTANTE: em Pacific C temos de dar uma indicação ao
Compilador para usar a biblioteca de virgula flutuante
ir a Options e ligar a opção Use floating point library

44
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

*/
//Declaracao e inicialização de Variaveis
//Se delta >=0 então tem raizes reais
//Senão tem raizes não reais
float A=0,B=0,C=0,Delta=0,X1R=0,X1I=0,X2R=0,X2I=0;
printf("Calcular as raizes da EQ Ax^2+Bx+C=0\n");
//Ler o coeficiente A
do
{
printf("\nA=");
scanf("%f", &A);
}
while (A==0);
//Ler o coeficiente B
printf("\nB=");
scanf("%f", &B);
//Ler o coeficiente C
printf("\nC=");
scanf("%f",&C);
//Processar as raizes
//Calcular Delta
Delta=(B*B-4*A*C);
//testar se delta >=0
if (Delta>=0)
{
X1R=((-B)+sqrt(Delta))/(2*A);
X2R=((-B)-sqrt(Delta))/(2*A);
X1I=0;
X2I=0;
}
else
{
X1R=(-B)/(2*A);
X1I=sqrt(-Delta)/(2*A);
X2R=X1R;
X2I=(-X1I);
}
//Escrever as raizes em formato numeros complexos a+i|b|
printf("\n-------------------------------------------");
printf("\nRaizes da Equação %fX^2+%fX+%f=0",A,B,C);
printf("X1=%10.2f+i%10.2f\n",X1R,fabs(X1I));
printf("X2=%10.2f+i%10.2f\n",X2R,fabs(X2I));

45
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

46
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

5.8 Arrays, Matrizes e Strings

Um array é uma colecção de variaveis partilhando um mesmo nome mas que podem ser
acedidas individualmente usando um indice. O indice aprece entre parentises rectos ([
]) depois do nome da variavel do tipo array. Ilustra na figura abaixo um array
unidimensional com nome Notas contendo 4 elementos (numerados de 1 a 4). O que é
mostrado são os nomes dos elementos não os seus valores.

Notas[1] Notas[2] Notas[3] Notas[4]

O numero entre parentises recto, como já referido anteriormente é o indice. Este


distingue as diferentes “variaveis” agrupadas sobre o nome Notas. Nota Importante: O
indice tem que ser um numero inteiro positivo. Em C o primeiro elemento é o Zero.
Noutras linguagem como Visual Basic podemos establecer se começa em o ou 1. Em
Raptor tem que ser um inteiro maior ou igual a 1.

Abaixo é mostrada uma forma diferente de visualizar a estrutura de um array, na


primeira linha aparece o indice e na segunda o valor de cada elemento associados a cada
indice.

Notas

1 2 3 4

87 93 77 82

O poder dos array nos programas é que nos permite processar inumeros valor com um
simples ciclo contado (loop). O corpo do ciclo processa cada elemento do array através
da indexação dos respecitos elementos.

Estudemos o exemplo: Calculo da média de 4 valores

47
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start

Numero_max_element
os ← 4

Soma ← 0

Contador ← 1

Loop

Yes
Contador>4

No

"Ler Valor:"
GET Notas[contador]

Soma ← soma + Notas


[contador]

contador ← contador +
1

Media ← soma /
Numero_max_element
os

PUT "Media
="+Media¶

End

Note que para um programador é indiferente processar 4 ou 4000 valores. Esta é a


grande vantagem do computador.

Exemplos com arrays:

Exercicio 1: Elabore um algoritmo que permita ler 6 notas de alunos de uma turma e os
respectivos numeros, calcule qual a nota maxima e minima e mostre quais os
respectivos numeros dos alunos que as obtiveram.

48
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start

Maxima ← 0

imax ← 0

Minima ← 21

imin ← 0

i←1

Loop

Yes
i>6

No

"Leia Numero Aluno :"


GET numero

"Leia Nota"
GET nota

numeros[i] ← numero

notas[i] ← nota

Yes No
nota>maxima

maxima ← nota

imax ← i

Yes No
nota<minima

minima ← nota

imin ← i

i←i+1

PUT "O Aluno "+numeros


[imax]+" tem a mais alta
Nota="+maxima¶
PUT "O aluno"+numeros
[imin]+" Tem a nota
baixa="+minima¶

End

49
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Exercicio 2: Altere o exercício anterior de forma que o algoritmo calcule a média da


turma.

50
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start

Maxima ← 0

imax ← 0

Minima ← 21

imin ← 0

i←1

Loop

Yes
i>6

No

"Leia Numero Aluno :"


GET numero

"Leia Nota"
GET nota

numeros[i] ← numero

notas[i] ← nota

Yes No
nota>maxima

maxima ← nota

imax ← i

Yes No
nota<minima

minima ← nota

imin ← i

i←i+1

PUT "O Aluno "+numeros


[imax]+" tem a mais alta
Nota="+maxima¶
PUT "O aluno"+numeros
[imin]+" Tem a nota
baixa="+minima¶

End

51
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Resolução em pesudo-código:

algoritmo "Calculo de Max_Min_Media"


// Função : Calcular o valor maximo, minimo e media de 6 notas
// Autor : Jorge Mota
// Data : 05-12-2006
// Secção de Declarações
var
notas: vetor [1..6] de real
numeros: vetor [1..6] de inteiro
maxima,minima,media,soma,nota : real
i,imax,imin,numero : inteiro
inicio
// Secção de Comandos
//Inicialização de variaveis
soma<-0
media<-0
maxima<-0
minima<-21
imax<-0
imin<-0
//Leitura e processamento
para i<-1 ate 6 faca
escreva("Numero do aluno=")
leia(numero)
escreva("Nota =")
leia(nota)
notas[i]<-nota
numeros[i]<-numero
soma<-soma+nota
se (nota>maxima) entao
maxima<-nota
imax<-i
fimse
se (nota<minima) entao
minima<-nota
imin<-i
fimse
fimpara
media<-soma/6
escreval("Nota maxima")
escreval(maxima)
escreval(imax)
escreval("Nota minima")
escreval(minima)
escreval(imin)
Escreva("Media =")
escreval(media)

52
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

fimalgoritmo

53
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Exercicio 3: Calculo das médias por aluno e disciplinas.

54
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start

NA ← 3

ND ← 3

Inicializa_array

i←1

j←1

Loop

Yes
i>NA

No

Loop

Yes
j>ND

No

"Nota do aluno numero


"+i+" da disciplina "+j
GET notas[i,j]
notas[i, NA + 1] ←
notas[i, NA + 1] +
notas[i, j]

temp ← notas[i, j] /
ND

notas[ND + 1, j] ←
notas[ND + 1, j] +
temp

PUT temp¶

j←j+1

notas[i, NA + 1] ←
notas[i, NA + 1] / NA

j←1

i←i+1

PUT "Terminou !!!"¶

End

55
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start

NA ← 3

ND ← 3

Inicializa_array

i←1

j←1

Loop

Yes
i>NA

No

Loop

Yes
j>ND

No

"Nota do aluno numero


"+i+" da disciplina "+j
GET notas[i,j]
notas[i, NA + 1] ←
notas[i, NA + 1] +
notas[i, j]

temp ← notas[i, j] / 3

notas[ND + 1, j] ←
notas[ND + 1, j] +
temp

PUT temp¶

j←j+1

notas[i, NA + 1] ←
notas[i, NA + 1] / NA

j←1

i←i+1

PUT "Terminou !!!"¶

End

56
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Pseudo-Código

57
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

5. Leitura validada de uma posição para o jogo do Galo:

Start

x←0

y←0

Loop

Yes x >= 1 and x<=3 and


y>=1 and y<=3
No

"X="
GET x

"Y="
GET y

Yes x >= 1 and x<=3 and No


y>=1 and y<=3

PUT "ATENÇÂO SÓ PODE


USAR VALORES ENTRE
[1 e 3]"¶

PUT "X="+x+"
Y="+y¶

End

58
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

6. Desenhe um algoritmo que escreva os primeiros n numeris de Fibonacci


uma série de fibonacci.

59
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

7. Desenvolva algoritmicamente em raptor o jogo do Galo?

60
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

5.9 Ponteiros
No campo da programação, um ponteiro ou apontador é um tipo de dado de uma
linguagem de programação cujo valor se refere diretamente a um outro valor alocado
em outra área da memória, através de seu endereço. Um ponteiro é uma simples
implementação do tipo referência da Ciência da Computação.

5.9.1 Arquitetura

Ponteiros são uma abstração da capacidade de endereçamento fornecidas pelas


arquiteturas modernas. Em termos simples, um endereço de memória, ou índice
numérico, é definido para cada unidade de memória no sistema, no qual a unidade é
tipicamente um byte ou uma word, o que em termos práticos transforma toda a memória
em um grande vector. Logo, a partir de um endereço, é possível obter do sistema o valor
armazenado na unidade de memória de tal endereço. O ponteiro é um tipo de dado que
armazena um endereço.

Na maioria das arquiteturas, um ponteiro é grande o suficiente para indexar todas as


unidades de memória presentes no sistema. Isso torna possível a um programa tentar
aceder a um endereço que corresponde a uma área inválida da memória, o que é
chamado de falha de segmentação. Por outro lado, alguns sistemas possuem mais
unidades de memória que endereços. Nesse caso, um esquema mais complexo, como o
de segmentação ou paginação, é utilizado para utilizar diferentes regiões da memória –
a estudar em arquitectura de computadores.

Para fornecer uma interface consistente, algumas arquiteturas fornecem E/S mapeada
em memória, o que permite que enquanto alguns endereços são referenciados como
áreas de memória, outros são referenciados como registradores de dispositivos do
computador, como equipamentos periféricos – muito utilizado em arquitectura de
dispositivos embebidos.

5.9.2 Utilidade

Os Ponteiros são directamente suportados sem restrições em C, C++, D e Pascal, entre


outras linguagens. São utilizados para construir referências, elemento fundamental para
construir a maioria das estruturas de dados, especialmente aquelas não alocadas em um
bloco contínuo de memória (heap), como listas encadeadas, árvores ou grafos. Também
são utilizados para especificar o endereço de funções de re-chamada (callback),
utilizando o conceito de ponteiro para função.

Em outras estruturas de dados, como listas encadeadas, ponteiros são usados como
referências para intercalar cada elemento da estrutura com seus vizinhos (seja anterior
ou próximo).

61
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Os Ponteiros também são utilizados para simular a passagem de parâmetros por


referência em linguagens que não oferecem essa construção (como o C). Isso é útil
se desejamos que uma modificação em um valor feito pela função chamada seja visível
pela função que a chamou. A mesma construção também é útil para que uma função
possa retornar múltiplos valores.

Linguagens como C e C++ permitem que ponteiros possam ser utilizados para apontar
para funções, de forma que possam ser invocados como uma função qualquer. Essa
abordagem é essencial para a implementação de modelos de callback, muito utilizados
actualmente em bibliotecas de código para manipulação de interfaces gráficas. Tais
ponteiros devem ser do tipo do retorno da função o qual apontam. Ponteiros para função
se assemelham a functores, ainda que o conceito função objeto seja mais abrangente.

Exemplos

Abaixo é mostrado o exemplo da declaração de uma lista encadeada em C, o que não


seria possível sem o uso de ponteiros:

/* a lista encadeada vazia é representada por NULL ou algum outro


símbolo */
#define LISTA_VAZIA NULL

struct link {
void *info; /* conteúdo do nó da lista */
struct link *prox; /* endereço do próximo nó da lista; LISTA_VAZIA
se este é o último nó */
};

5.10 Estruturas avançadas de dados – Estruturas e uniões;


Enumerações e tipos definidos pelo utilizador

5.11 Ficheiros de Texto em C, Rapor e VisualAlg

Um ficheiro é uma colecção de dados que reside num disco ou outro meio(dispositivo)
persistente de armazenamento de dados (ex: pendrive). O mais comum dos tipos de
ficheiros é o designado ficheiro de texto (text file), que é normalmente um conjunto
organizado de linhas de texto que conseguimos ler. Este tipo de ficheiro pode ser criado
com um programa tipo Notepad do Windows. Normalmente a extensão é .txt.

Os ficheiros são usados essencialmente pelos programas para guardar dados entre
execuções. Exemplos o ficheiro com a máxima pontuação obtida num jogo ou o
ficheiro de configuração de um determinado programa(INI). Um ficheiro como este
pode conter um ou milhares de elementos (linhas).

62
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Os ficheiros também são muito usados em programação para evitar a reintrodução de


extensos conjuntos de dados. É normal na vida real que os programas trabalhem com
centenas de milhares de dados ou mesmo milhões. Não parece facilmente realizável
serem reintroduzidos de cada vez que se corre o programa!

Finalmente uma última utilização como forma de output final de um programa(saida).


Nestes outputs podemos formatar os dados para os mais diversos efeitos – impressão,
novo input etc.

Em Raptor os programas podem ler ou escrever directamente de ficheiros de texto por


redireccionamento. No raptor quando estamos em modo leitura de ficheiro (ou escrita
não podemos simultaneamente fazer leituras de outros dispositivos – ex: teclado ou
output para a Master Console.

Em raptor a leitura dos dados do ficheiro é feita linha a linha e no caso de não
conhecermos o tamanho do ficheiro podemos usar a função End_Of_Input, que
devolve true nesta situação.

Exemplo de redireccionamento:

Chamamos a função,

Redirect_Input("file.txt")

ou

Redirect_Input("C:\Documents and Settings\file.txt");

Exercício:

Implementar em raptor um algoritmo que gere um ficheiro com


10000 valor aleatórios entre 1 e 10000.O nome do ficheiro
deve ser “bateria_dados_10000.txt”

Resolução em Raptor:

63
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start

Redirect_Output
("bateria_dados_10000
.txt")

n ← 10

i←1

Loop

Yes
i>10

No

Num ← Floor(random
* 10000)

PUT Num¶

i←i+1

Redirect_Output(no)

PUT "Terminou a
Geração !"¶

End

6 Ordenação e Pesquisa

6.1 Pesquisa

Vamos considerar três tipos de pesquisa em sequências de dados ou valores (vectores,


listas ou ficheiros) : Sequencial ou Linear, Dicotómica ou Binária e Hashing ou
pesquisa por dispersão. Dada a complexidade deste último método o seu estudo fica
para uma disciplina de estruturas de dados num próximo semestre.

64
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Pesquisa sequencial ou linear

Na área de informática, ou Ciência da Computação, costuma-se usar o termo busca


linear para expressar um tipo de pesquisa em vectores ou listas de modo sequencial, ou
seja, elemento por elemento, de modo que a função do tempo em relação ao número de
elementos é linear, por outras palavras, cresce proporcionalmente. Num vector
ordenado, essa não é a pesquisa mais eficiente, a pesquisa (ou busca) binária, por
exemplo, é um tipo de pesquisa com o gráfico de tempo logaritmo, portanto muito mais
eficiente[pt.wikipedia.org]. No entanto a pesquisa linear é a pesquisa que permite fazer
buscas em sequências não ordenadas e como tal aplicável em grande numero de
situação em que pretendemos conhecer as as características da sequência – maior valor;
menor valor; primeiro valor; melhor valor; pior valor [ver capitulo 12, pág. 428
Introdução a Programação usando C, António Rocha FCA]. A complexidade desse
algoritmo é da ordem de n, onde n é o tamanho do vector de busca.

Código em C
/**
* Retorna -1 caso não encontre ou a posição
* caso encontre.
*/
int procura(char vetor[], int tamanho, char elementoProcurado) {
int i;
for (i = 0; i < tamanho; i++) {
if (vetor[i] == elementoProcurado) {
return i;
}
}

return -1;
}

Pesquisa binária

A pesquisa ou busca binária ( em inglês binary search algorithm) é um algoritmo de


busca em vectores que requer acesso aleatório aos elementos do mesmo. Ela parte do
pressuposto de que o vector está ordenado, e realiza sucessivas divisões do espaço de
busca comparando o elemento procurado (chave) com o elemento no meio do vector. Se
o elemento do meio do vector for a chave, a busca termina com sucesso. Caso contrário,
se o elemento do meio vier antes do elemento procurado, então a busca continua na
metade posterior do vector. E finalmente, se o elemento do meio vier depois da chave, a
busca continua na metade anterior do vector. A complexidade desse algoritmo é da
ordem de log2 n, onde n é o tamanho do vector de busca.

Um pseudocódigo recursivo para esse algoritmo: dados V o vector com elementos


comparáveis, n seu tamanho e o elemento que se deseja encontrar:

65
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

BUSCA-BINÁRIA (V[], inicio, fim, e}


i recebe o índice no meio de inicio e fim
se V[i] é igual a e
então devolva o índice i # encontrei e
senão se V[i] vem antes de e
então faça a BUSCA-BINÁRIA(V, i+1, fim, e)
senão faça a BUSCA-BINÁRIA(V, inicio, i-1, e)

Código em C
int PesquisaBinaria(char chave,char k[],int N)
{
int inf,sup,meio;
inf=0;
sup=N-1;
while (inf<=sup) {
meio=(inf+sup)/2;
if (chave==k[meio])
return meio;
else if (chave<k[meio])
sup=meio-1;
else
inf=meio+1;
}
return -1; /* não encontrado */
}

6.1.1 Exercício - Pesquisa sequencial ou linear em lista desordenada, lida de um


ficheiro externo (“dados.txt” com 10 elementos).

66
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

67
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

6.1.2 Exercício - Pesquisa Binária em lista ordenada. A lista é lida de ficheiro de texto
com uma sequência ordenada. Implementação feita em Raptor.

68
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

69
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

6.1.3 Exercício - Pesquisa Binária em lista ordenada com inserção na posição correcta
na situação do elemento não constar na sequência. A lista de elementos é lido de
ficheiro de texto exterior. Implementação feita em Raptor.

Start

Redirect_Input
("c:\Dicotomica_
dados.txt")

n ← 10

i←1

Loop

Yes
i>=11

No

""
GET Lista[i]

i←i+1

Redirect_Input(no)

"Qual o Valor a
Procurar?"
GET valor

inf ← 1

sup ← 10

Flag ← 1

Loop

Yes (inf>sup) or
(Flag=0)
No

meio ← floor((inf +
sup) / 2)

Yes No
Valor=Lista[meio]

Yes Valor<=Lista No
Flag ← 0 [meio]

sup ← meio - 1 inf ← meio + 1

Yes No
(Flag=0)

PUT "Encontrou o
PUT "Não
Valor na Posição
Encontrou ..."¶
"+meio¶

inserir_ordenada

End

70
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

6.2 Ordenação

Algoritmo de ordenação em ciência da computação é um algoritmo que coloca os


elementos de uma dada sequência numa certa ordem – por outras palavras, efectua a
ordenação completa ou parcial. As ordens mais usadas são a numérica e a
lexicográfica.

Existem várias razões para se ordenar uma sequência. Uma delas é a possibilidade se
aceder seus dados de modo mais eficiente.

Em termos de algoritmos de ordenação vamos considerar duas grandes categorias:

1) Algoritmos de ordenação Interna

A lista de valores a ordenar encontra-se em estruturas de dados em memória (vectores


ou listas).

1) Algoritmos de ordenação externa

Algoritmos que fazem a ordenação de listas de valores em ficheiros externos.

Todos os algoritmos que vamos estudar são da primeira categoria deixando para
posterior disciplina (unidade curricular) no curso o estudo de algoritmos de ordenação
externa.

7 Bubble sort

O bubble sort, ou ordenação por flutuação (literalmente "por bolha"), é um algoritmo de


ordenação dos mais simples. A ideia é percorrer o vector diversas vezes, a cada
passagem fazendo flutuar para o topo o menor elemento da sequência. Essa
movimentação lembra a forma como as bolhas num tanque de água procuram o seu
próprio nível, e daí o nome do algoritmo.

No melhor caso, o algoritmo executa (n2) / 2 operações relevantes. No pior caso, são
feitas 2n2operações. No caso médio, são feitas (5n2) / 2 operações. A complexidade
desse algoritmo é de Ordem quadrática. Por isso, ele não é recomendado para
programas que precisam de velocidade e operam com uma quantidade elevada de dados.

O algoritmo pode ser descrito em pseudocódigo como segue representado abaixo. V é


um VECTOR de elementos que podem ser comparados e n é o tamanho desse vector.

BUBBLESORT (V[], n)
1 houveTroca <- verdade # uma variável de controle
2 enquanto houveTroca for verdade faça
3 houveTroca <- falso
4 para i de 1 até n-1 faça
5 se V[i] vem depois de V[i + 1]
6 então troque V[i] e V[i + 1] de lugar e
7 houveTroca <- verdade

71
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação em C

void bubble(int x[],int n)


{
int troca, i, j, aux;
for (i = n-1; i > 0; i--)
{
// o maior valor entre x[0] e x[i] vai para a posição x[i]
troca = 0;

for (j =0 ; j < i-1; j++)


{
if (x[j] > x[j+1])
{
aux = x[j];
x[j] = x[j+1];
x[j+1] = aux;
troca = 1;
}
}

if (!troca) return;
}
}

72
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação em Raptor Bubble Sort:

73
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação Bubble Sort


Start

Carregar_Lista

Troca ← 1

i←n

Loop

Yes
(i<=1) or (Troca=0)

No

Troca ← 0

j←1

Loop

Yes
(j>i - 1)

No

Yes (Lista[j]>Lista[j + No
1])

Swap

Troca ← 1

j←j+1

i←i-1

PUT "Terminou!"¶

End

74
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start Start

Redirect_Input
temp ← Lista[j] ("c:\bateria_dados_100
0.txt")

Lista[j] ← Lista[j + 1] n ← 100

Lista[j + 1] ← temp k←1

End Loop

Yes
k>n

No

""
GET Lista[k]

k←k+1

Redirect_Input(no)

End

75
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

76
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Ordenação por Selecção

O selection sort , ou ordenação por selecção, é baseado no seguinte principio: passar


sempre o menor valor do vector para a primeira posição (ou o maior dependendo da
ordem requerida), depois o do segundo menor valor para a segunda posição, e assim
sucessivamente para os (n-1) elementos restantes, até aos últimos dois elementos.

Código em C
void selectionSort(int vetor[],int tam)
{
int i,j;
int min,aux;
for (i=0;i<tam-1;i++)
{
min=i;
for (j=i+1;j<tam;j++)
{
if (vetor[j]<vetor[min])
min=j;
}

aux=vetor[i];
vetor[i]=vetor[min];
vetor[min]=aux;
}
}

77
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação em Raptor do algoritmo de ordenação por Selecção:

78
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação dos subprogramas Troca e Carregar Lista:

Start Start

Redirect_Input
temp ← Lista[i] ("c:\bateria_dados_100
0.txt")

Lista[i] ← Lista
n ← 100
[posicao]

Lista[posicao] ← temp k←1

End Loop

Yes
k>n

No

""
GET Lista[k]

k←k+1

Redirect_Input(no)

End

79
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Insertion sort

Insertion sort, ou ordenação por inserção, é um algoritmo simples de ordenação,


eficiente quando aplicado a um pequeno número de elementos. Em termos gerais, o que
faz é percorrer um vector de elementos da esquerda para a direita e à medida que avança
vai deixando os elementos mais à esquerda ordenados. O algoritmo de inserção
funciona da mesma maneira como muitas pessoas ordenam cartas num jogo de cartas
como o poquer.

Implementação em C
void insertSort(int a[], size_t length) {
int i, j, value;

for(i = 1; i < length; ++i) {


value = a[i];
for (j = i - 1; j >= 0 && a[j] > value; --j) {
a[j + 1] = a[j];
a[j] = value;
}
}
}

80
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação em Raptor:

81
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start Start

Redirect_Input
Lista[j + 1] ← Lista[j] ("c:\bateria_dados_100
0.txt")

Lista[j] ← Valor n ← 100

End k←1

Loop

Yes
k>n

No

""
GET Lista[k]

k←k+1

Redirect_Input(no)

End

82
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Shell sort

Criado por Donald Shell em 1959, Shell sort é o mais eficiente algoritmo de
classificação entre os de complexidade quadrática. Basicamente o algoritmo passa
várias vezes pela lista dividindo o grupo maior em grupos menores. Nos grupos
menores é aplicado o método da ordenação por inserção.

Código em C
void shellSort( int * vet, int size ){

int i , j , value;
int gap = 1;

do {gap = 3*gap+1;} while ( gap < size );


do {
gap /= 3;
for ( i = gap; i < size; i++ ){
value =vet[i];
j = i - gap;
while ( j >= 0 && value < vet[j] ){
vet [j + gap] =vet[j];
j -= gap;
}
vet [j + gap] = value;
}
} while ( gap > 1);
}

83
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação em Raptor:

84
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

85
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Procedimento Inicializar a Lista com 100 elementos:

Start

Redirect_Input
("c:\bateria_dados_100
0.txt")

n←4

k←1

Loop

Yes
k>n

No

""
GET Lista[k]

k←k+1

Redirect_Input(no)

End

86
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Quicksort

Algumas etapas do algoritmo Quicksort.

O algoritmo Quicksort é um método de ordenação muito rápido e eficiente, inventado


por C.A.R. Hoare em 1960, quando visitou a Universidade de Moscou como estudante.
Foi publicado em 1962 após uma série de refinamentos.

A sua premissa básica é dividir o problema de ordenar n itens em dois problemas


menores. Em seguida, os problemas menores são ordenados de forma independente e os
resultados são combinados para produzir a solução do problema todo [pt.wikipeia.org].

Complexidade do Quicksort

• Complexidade de tempo: θ(n lg2 n) no melhor caso e no caso médio e θ(n2) no


pior caso;
• Complexidade de espaço: θ(lg2 n) no melhor caso e no caso médio e θ(n) no pior
caso.

87
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Algoritmo em português estruturado

proc quicksort (x:vet[n] int; ini:int; fim:int; n:int)


var
int: i,j,x,aux;

início
i <- ini;
j <- fim;
x <- x[(ini + fim) div 2];
repete
enquanto (x[i] < x) faça
i <- i + 1;
fim-enquanto;
enquanto (x[j] > x) faça
j <- j - 1;
fim-enquanto;
se (i <= j) então
aux <- x[i];
x[i] <- x[j];
x[j] <- aux;
i <- i + 1;
j <- j - 1;
fim-se;
até_que (i >= j);
se (j > ini) então
exec quicksort (x, ini, j, n);
fim-se;
se (i < fim) então
exec quicksort (x, i, fim, n);
fim-se;
fim.

Implementação em raptor (versão recursiva – não executável em


Raptor)

88
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start

Carregar_Lista

inicio ← 1

fim ← n

Quicksort

PUT "Terminou!"¶

End

89
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação do procedimento quicksort:

90
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start

i ← inicio

j ← fim

x ← Lista[floor((inicio +
fim) / 2)]

Loop

Loop

Yes
Lista[i]>=x

No

i←i+1

Loop

Yes
Lista[j]<=x

No

j←j-1

Yes No
i<=j

aux ← Lista[i]

Lista[i] ← Lista[j]

Lista[j] ← aux

i←i+1

j←j-1

Yes
i>=j

No

Yes No
j>inicio

fim ← j

Quicksort

Yes No
i<fim

inicio ← i

Quicksort

End

91
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação da rotina que carrega a Lista:

Start

Redirect_Input
("c:\bateria_dados_1000.txt")

n ← 10

k←1

Loop

Yes
k>n

No

""
GET Lista[k]

k←k+1

Redirect_Input(no)

End

92
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação em C
void sort(int array[], int begin, int end) {
if (end - begin > 1) {
int pivot = array[begin];
int l = begin + 1;
int r = end;
while(l < r) {
if (array[l] <= pivot) {
l++;
} else {
r--;
swap(array[l], array[r]);
}
}
l--;
swap(array[begin], array[l]);
sort(array, begin, l);
sort(array, r, end);
}
}

Implementaçao usando 'fat pivot':

void sort(int array[], int begin, int end) {


int pivot = array[begin];
int i = begin + 1, j = end, k = end;
int t;

while (i < j) {
if (array[i] < pivot) i++;
else if (array[i] > pivot) {
j--; k--;
t = array[i];
array[i] = array[j];
array[j] = array[k];
array[k] = t; }
else {
j--;
swap(array[i], array[j]);
} }
i--;
swap(array[begin], array[i]);
if (i - begin > 1)
sort(array, begin, i);
if (end - k > 1)
sort(array, k, end);
}

93
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

7.1 Filas, Listas e Pilhas

94
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

8 Execicios de algoritmia com cálculo numérico

8.1.1 Notas sobre integração de uma função

Integral simples:
xDireita

∫ f ( x) * dx
xEsquerda

Este integral representa a área sob a curva no intervalo de xEsquerda a xDireita. A


curva é definida pela função f(x). O “dx” indica que estamos a integrar em ordem ao
eixo do x.

Representação Visual do Integral:

95
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

8.1.2 Integração usando a Regra de Simpson


A regra de Simpson usa como forma de estimativa do valor de um integral, em dado
intervalo, o calculo da área definida pela sub-divisão rectangular da mesma. Dado um
intervalo de uma função f(x), o método subdivide o intervalo de integração em n sub-
intervalos, calculando depois a área de cada sub-intervalo rectangular através da
multiplicação da altura do mesmo pela largura de cada sub-divisão. A altura é dada pelo
valor da função f(x) no ponto médio de cada sub-divisão, e a largura é dada pelo intervalo a
dividir pelo numero de sub-divisões - n. Depois de calculadas todas as áreas o somatório
destas é e estimativa de todo o integral no intervalo dado (área abaixo da função). É
importante notar que quanto maior for o numero de sub-divisões maior a precisão da área
total obtida.

Formulas importantes:

∑ ∆X * f ( xEsquerda + i * ∆X − X / 2)
i =1

Que pode ser re-escrita como:


n
( xDireita − xEsquerda) / n * ∑ f ( xEsquerda + ∆X (i − 1 / 2))
1=1
Descrição dos termos:

N=numero de sub-intervalos no intervalo de

∆X = ( xDireita − xEsquerda) / n = Largura do sub-intervalo

f ( xEsquerda + i * ∆X − ∆X / 2) = Altura do sub-intervalo

Representação Visual:

96
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

97
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start

Start

a←1

Parâmetros passados para a função


xEsquerda ← a
b←2

Quanto maior o numero de intervalos mais preciso o resultado


n ← 1024
xDireita ← b
F_string ← "(3 * x * x - 2 *
x)"

nDivs ← n
integrar_rect

PUT "Integrar "+F_string+"


no intervalo de 0 a 2, então a
area= "+area¶
area ← 0

End

deltax ← (xDireita -
xEsquerda) / nDivs

midpointx ← xEsquerda +
DeltaX / 2

i←0

Loop

Yes
i>=nDivs

No

x ← midpointx

Calculo do acumulado e funciona co


area ← area + (3 * x * x - 2 *
x) * deltax

midpointx ← midpointx +
deltax

i←i+1

End

98
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start

Parâmetros passados para a função


xEsquerda ← a

xDireita ← b

nDivs ← n

area ← 0

deltax ← (xDireita -
xEsquerda) / nDivs

midpointx ← xEsquerda +
DeltaX / 2

i←0

Loop

Yes
i>=nDivs

No

x ← midpointx

Calculo do acumulado e funciona como valor de retorno da função


area ← area + (3 * x * x - 2 *
x) * deltax

midpointx ← midpointx +
deltax

i←i+1

End

99
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Notas sobre integração usando a técnica de Monte Carlo


A técnica de integração de Monte Carlo baseia-se na estimativa obtida pela teoria das
probabilidades. Dado um intervalo (xEsquerda, xDireita) de uma função, f(x) que está
limitada por uma constante M, o método de Monte Carlo aleatoriamente selecciona pontos
dentro da “caixa” de restrições horizontal (intervalo de integração) e vertical (constante M)
e determina se o ponto fica acima ou a baixo da função. A probabilidade de que o ponto
esteja abaixo de f(x) é igual, na proporção da “caixa” de restrição, à probabilidade de estar
acima de f(x). Quantos mais pontos forem escolhidos mais precisa a estimativa e portanto
mais precisa a área final estimada.

Formulas Importantes:

Área Total = M*(xEsquerda-xDireita)

A área abaixo de f(x) = Pr(Yaleatório<=f(Xaleatório))*M*(xDireita-xEsquerda)

Descrição dos termos da formula:

M = um valor y tal que M>=f(x) para todos os XEsquerda<=X>=Xdireita)

Yaleatório = Um Y aleatório escolhido de forma que 0<=Yaleatório<=M

Xaleatório = UmX aleatório de forma que xEsquerda<=Xaleatório<=xDireita

F(Xaleatório)=f(x) calculado no ponto Xaleatório

Pr(Yaleatório<=f(Xaleatório))= Probabilidade aleatória de o ponto estar abaixo de f(x)

Representação Visual:

100
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Anexo 2
Teste Tipo teórico

Pergunta 1 (2 valor)

Coloque por ordem crescente de data de aparecimento as seguintes


linguagens de programação (da mais antiga para a mais recente)

Fortran
LISP
BASIC
C#
JAVA
C
C++
Visual Basic
Cobol

Pergunta 2 (2 valores)

Em termos metodológicos no desenho e implementação algoritmica usamos


essencialmente duas abordagens a:

Top-Down e a Bottom-up

Explique de forma clara em que consistem estas abordagens e em que


situações aplicaria um e outro ou ambos.

Pergunta 3 (2 valores)

Qual a diferença entre função e procedimento? Em ambos podemos usar


parâmetros, explique o que são, para que se usam e que tipos de passagens
existem( quanto ao modo como é feita a passagem) ?

Pergunta 4 (3 Valores)

a)Analise o seguinte algoritmo em VisualAlg 2.0 e escreva qual o resultado do


mesmo para um numero de elementos igual a 10?
b)Substitua a estrutura de controlo REPETIR … ATE () por uma ENQUANTO
() FAZER … FIMENQUANTO

algoritmo "FIBO"
// Função :FIBO
// Autor :JORGE MOTA
// Data : 29-01-2007
// Secção de Declarações
var

101
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

n,a,b,nFin: inteiro
inicio
// Secção de Comandos
escreva("Numero de elementos:")
Leia (nFin)
n <- 0
a <- 0
b <- 1
REPITA
escreval(a)
escreval(b)
n <- n + 2
a <- a + b
b <- b + a
ATE (n > (nFin-2))
fimalgoritmo

Pergunta 5 (3 valores)

Desenvolva um algoritmo em Raptor (fluxograma) que permita converter uma


string para maisculas:

Exemplo:

esTe e um teste de algoritmia. Æ ESTE E UM TESTE DE ALGORITMIA

Pergunta 6 (3 valores)

Implemente em raptor (fluxograma) e em C um algoritmo que calcule a altura


ao solo de um passageiro durante um passeio na roda gigante tal que :

Vamos imaginar, que uma roda leva 12 cadeiras igualmente espaçadas ao


longo do seu perímetro, que o seu raio mede 10 metros e que o ponto mais
baixo atingido ao longo do percurso círcular está a 0,5 metros do solo. Sabe-se
também que uma roda demora cerca de 30 segundos a efectuar uma rotação
completa.

102
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Com : h=10.sen(pt/15), t pertencente ao intrevalo fechado de [0,30].

Pergunta 7 (2 Valores)

Implemente iterativamente o seguinte seguinte algoritmo (função) de cálculo de


um factorial:

funcao factorial (v: inteiro): inteiro

inicio
se v <= 2 entao

retorne v

senao
retorne v * factorial(v-1)

fimse
fimfuncao

Pergunta 8 (3 Valores)

Explique o algoritmo de ordenação Bubble Sort, implemente o mesmo em


raptor (Fluxograma) para uma ordenação crescente, partindo do princípio que a
lista a ordenar está contida num array de nome LISTA e que tem n elementos.

103
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Teste Tipo Prática

Pergunta 1

Implemente em linguagem Visual Raptor( ou em Fluxograma tradicional) e em


linguagem C um algoritmo que permita estimar o valor do integral de uma
função simples f(x): 3x 2 − 2 x , no intervalo (0,3) usando a regra de integração
numérica de Simpson.
Notas para a implementação: A regra de Simpson usa rectângulos para
aproximar a área (integral) no intervalo (a,b) de uma função f(x). A área de
cada rectangulo é calculada usando como base a largura de cada rectangulo e
como altura o valor da função f(x) calculada no ponto médio de cada rectângulo
e no final é somado o conjunto das áreas. Este valor final é o valor aproximado
do integral naquele intervalo.

Resposta

A regra de Simpson usa como forma de estimativa do valor de um integral, em dado


intervalo, o calculo da área definida pela sub-divisão rectangular da mesma. Dado um
intervalo de uma função f(x), o método subdivide o intervalo de integração em n sub-
intervalos, calculando depois a área de cada sub-intervalo rectangular através da
multiplicação da altura do mesmo pela largura de cada sub-divisão. A altura é dada pelo
valor da função f(x) no ponto médio de cada sub-divisão, e a largura é dada pelo intervalo a
dividir pelo numero de sub-divisões - n. Depois de calculadas todas as áreas o somatório
destas é e estimativa de todo o integral no intervalo dado (área abaixo da função). É
importante notar que quanto maior for o numero de subdivisões maior a precisão da área
total obtida ( figura são usados 10 sub-divisões mas na implementação vamos usar 1024
para maior precisão).

104
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

8.1.3 Formulas importantes :

n
8.1.4 ∑ ∆X * f ( xEsquerda + i * ∆X − X / 2)
i =1

Que pode ser re-escrita como:


n
( xDireita − xEsquerda) / n * ∑ f ( xEsquerda + ∆X (i − 1 / 2))
1=1
Descrição dos termos:

8.1.5 N = numero de subintervalos no intervalo de integração

8.1.6 ∆X = ( xDireita − xEsquerda) / n = Largura do subintervalo

8.1.7 f ( xEsquerda + i * ∆X − ∆X / 2) = Altura do subintervalo

Implementação em Raptor

Start

a←1

b←2

Quanto maior o numero de intervalos mais preciso o resultado


n ← 1024

F_string ← "(3 * x * x - 2 *
x)"

integrar_rect

PUT "Integrar "+F_string+"


no intervalo de 0 a 2, então a
area= "+area¶

End

105
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start

Parâmetros passados para a função


xEsquerda ← a

xDireita ← b

nDivs ← n

area ← 0

deltax ← (xDireita -
xEsquerda) / nDivs

midpointx ← xEsquerda +
DeltaX / 2

i←0

Loop

Yes
i>=nDivs

No

x ← midpointx

Calculo do acumulado e funciona como valor de retorno da função


area ← area + (3 * x * x - 2 *
x) * deltax

midpointx ← midpointx +
deltax

i←i+1

End

106
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação em Linguagem C:

/**********************************************************/
/* */
/* Autor: JM */
/* Data: 25 Janeiro, 2007 */
/* Disciplina: Introdução a Ciência dos Computadores */
/* Professor: Jorge Mota */
/* Descrição: Este programa integra uma função, embebida*/
/*No código e representada por F, no intervalo definido */
/*A a B usando a regra de Simpson. */
/* */
/**********************************************************/

#include <math.h> /* Usar a biblioteca matemática */


#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define SEED 5

/* Formula */
#define A 1.0
#define B 3.0
#define FORMULA (3 * x * x - 2 * x)
#define F_STRING "(3 * x * x - 2 * x)"

/* Esta é a função matemática a ser integrada. */


/* Tem uma variável x como entrada e devolve F(x). */

double f(double x)
{
return FORMULA;
}

/* Esta função integra f entre xEsquerda e xDireita usando a regra de


simpson */
/* É feita uma divisão da função f em nDivs rectângulos */

/* e para cada rectângulo é calculada a área do mesmo usando como


altura o ponto médio de cada sub-divisão. */

/* A função requer que no intervalo (xEsquerda e x Direita),


calculemos o numero de divisões. */

/* O valor do integral no intervalo é o somatório das areas


rectangulares. Quantas mais sub-divisões mais preciso é o resultado.
*/

double integrar_rect(double xEsquerda, double xDireita, double


f(double), int nDivs)
{
int i; /* Variavel contadora */
double area = 0.0; /* area estimada */
double deltaX = (xDireita - xEsquerda)/nDivs; /* largura do Sub-
divisão */
double midpointX; /* ponto medio */

107
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

midpointX = xEsquerda + deltaX/2.0;

for (i = 0; i < nDivs; ++i)


{
area += f(midpointX) * deltaX; /* Acumula a área */
midpointX += deltaX; /* proximo rectangulo*/
}

return area;
}

/* Main() é responsável por chamar o método que calcula a integração*/


/* e imprimir a area calculada */

int main(void)
{
int n; /* numero de rectangulos */
double s; /* area estimada pela regra de simpson */

srand(SEED);

printf("\n");
printf("Integrar F(x) = %s de %5.3f to %5.3f\n", F_STRING, A, B);
printf("\n");

s = integrar_rect(A, B, f, n);
printf(" Regra de Simpson: Area com 1024 sub-intervalos
= %9.6f\n", s);

return 0;
}

Esta pergunta vale 20 valores em 20.

Critérios para correcção:

Se o aluno consegue descrever em português corrente os passos do algoritmo 10%

Se aluno estrutura convenientemente o algoritmo em funções(Métodos e Constantes) 10%

Se o aluno comenta correcta e completamente o código 10%

Se o aluno define o algoritmo de integração correctamente, separando convenientemente


variáveis, ciclo de calculo acumulado da área e impressão formatada do output em Raptor 30%

Se o aluno define o algoritmo de integração correctamente, separando convenientemente


variáveis, ciclo de calculo acumulado da área e impressão formatada do output em C 20%

Se o Nome das variaveis está adequado a sua função e não gera confusão com nomes
reservados 5%

Se o algoritmo em Raptor funciona sem erros 10%

Se o algoritmo em C funciona Correctamente 5%

108
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Anexo: resolução da FREQUÊNCIA DE Janeiro de 2007

Licenciatura em Informática 1º Ano - 1º Semestre


Introdução a Ciência dos Frequência - Resolução
Computadores – 1º Ano
Data : 5-02-2007 Duração : 60 Minutos
Parte Teórica Prof. : Jorge Mota

Numero : Nome :

Pergunta 1 (2 valor)

Explique o que é a Heap e a Stack num modelo de memória de uma linguagem


de programação de alto nível como o C. Fale um pouco sobre a preocupação
que deve ter com estas estruturas quando se usam ponteiros e alocação
dinâmica de memória.

Resposta:

Uma arquitectura tradicional de memória para um programa em C, ou


linguagens similares, inclui as seguintes áreas:

Heap

Stack

Variaveis Globais

Instruções Programa

Em linguagens como o C podemos dinâmicamente alocar espaço na Heap, e


usar este espaço para as nossas estruturas de dados. A gestão do espaço
alocado fica da responsabilidade do programador que deve ter a
responsabilidade de limpar (libertar) este espaço sempre que já não for
necessário. Normalmente usa comandos de alocação dinâmica de espaço na

109
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Heap, do tipo malloc(size). Este espaço é depois manipulado/ endereçado por


estruturas tipo ponteiro. Se isto não acontece podemos criar situações de erro
grave de sistema por falta de espaço, nomeadamente:

1) Quando a stack cresce e não dispõem de mais espaço.


2) Quando tentamos alocar mais espaço na Heap.

Esta é também uma fórmula comum de ataque aos programas, ficando o


computador a mercê de um ataque de Hacker.

A Stack é a área de memoria gerida pelo próprio programa, para as variaveis


locais, parametros e outros.

As variaveis globais e constantes usam o espaço reservado ao programa (no


topo ou no inicio da memoria usada pelo programa).

Pergunta 2 (2 valores)

Implemente em VisualAlg e C um algoritmo que calcule os numeros primos até


um determinado valor inteiro.

Resposta:

Um número primo é aquele que só é divisivel pela unidade e ele próprio.


Se pretendemos imprimir a lista de numero primos até um valor, vamos fazer
um ciclo que itera até este valor e para cada um testa se é primo (força bruta),
se for é impresso senão passa ao seguinte.

Para n=100
Temos a seguinte lista:

2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97

Em VisulAlg:

algoritmo "Primos"
// Função : Calcular Primos
// Autor : JM
// Data : 23-02-2007
// Secção de Declarações
var
sai,i,j,n:inteiro

inicio
// Secção de Comandos
escreva ("Ler quantos numeros(>4):")
leia (n)
escreval(2)

110
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

escreval(3)
para i<-4 ate n faca
sai<-0
j<-2
enquanto (j<i) e (sai=0) faca
se ((i%j)=0) entao
sai<-1
senao
j<-j+1
fimse
fimenquanto
se sai=0 entao
escreval(i)
fimse
fimpara
fim

Em C:
#include <stdio.h>
void main(void)
{

int sai,i,j,n;
printf("Numeros primos at-->");
scanf("%d",n);
for(i=4;i<n;i++)
{
j=2;

sai=0;
while((j<i) && (sai==0))
{
if (i%j==0)
sai=1;
else
j=j+1;

}
if (sai==0)
printf("\n%d ",i);

}
printf("\nTerminou o calculo");
}

Pergunta 3 (2 valores)

Na estruturação de algoritmos e implementação em linguagens de alto nível é


comum decompormos o programa em problemas mais pequenos. A
implementação destas unidades mais pequenas em linguagens como o C ou
linguagens algoritmicas como o VisualAlg é feita sob a forma de funções ou

111
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

procedimentos. Explique como implementar em VisualAlg e C procedimentos e


funções e como se processam os diversos tipos de passagens de parâmetros.

Resposta:

Quer o C quer o VisualAlg possuem Funções e Procedimentos e respectivas


passagens de parãmetros por valor e referência.

Usamos Funções sempre que pretendemos atomizar funcionalidades do nosso


programa e que seja devolvido um valor. Em C isto é feito implicitamente
designando o nome da <função>. Em VisualAlg 2.0 usamos a palavra
reservada funcao. Para os procedimentos o C usa igualmente a forma implicita
só que não é especificado nenhum tipo de dados a devolver - void.
Já o visualAlg 2.0 utiliza a palavra reservada Procedimento.
Todas estas construções suportam passagem de parãmetros por valor e
referência ou seja no primeiro a variavel chamadora não é alterada e na
segunda o que usamos é uma referência para a mesma memória onde está
instanciada a variavél chamadora, quer dize,r é como usar um aliás para esta
variavel.

Sintaxe em VisualAlg:

funcao <nome-de-função> [(<seqüência-de-declarações-de-parâmetros>)]:


<tipo-de-dado>

// Secção de Declarações Internas


inicio
// Secção de Comandos
fimfuncao

procedimento <nome-de-procedimento> [(<seqüência-de-declarações-de-


parâmetros>)]
// Secção de Declarações Internas
inicio
// Secção de Comandos
fimprocedimento

Passagem de parâmetros por referência (negrito) por valor a (italico):

procedimento soma (x,y: inteiro; var resultado: inteiro)

funcao soma (x,y: inteiro): inteiro

Em C:

Void nome(<tipo> var,<tipo> *var)

112
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

int nome(<tipo> var,<tipo> *var)

Return n

Pergunta 4 (3 Valores)

a)Analise o seguinte algoritmo em VisualAlg 2.0 e escreva qual o resultado do


mesmo para um numero de elementos igual a 12?
b)Substitua a estrutura de controlo ENQUANTO () FAZER … FIMENQUANTO
por uma REPETIR … ATE () .

algoritmo "FIBO_ENQUANTO"

// Autor :JORGE MOTA


// Data : 29-01-2007
// Substituir um repetir por enquanto
// Secção de Declarações
var
n,a,b,nFin: inteiro
inicio
// Secção de Comandos
escreva("Numero de elementos:")
Leia (nFin)
n <- 0
a <- 0
b <- 1
enquanto (n<=nFin-2) faca
escreval(a)
escreval(b)
n <- n + 2
a <- a + b
b <- b + a

113
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

fimenquanto
fimalgoritmo

Resposta:
a)

n 0 2 4 6 8 10 12
a 0 1 3 8 21 55 144
b 1 2 5 13 34 89 233
N<=nFin-2 V V V V V V F
Escreva a 0 1 3 8 21 55
Escreva b 1 2 5 13 34 89

Sequência Impressa: 0,1,1,2,3,5,8,13,21,34,55,89

b)
algoritmo "FIBO_Repetir"

// Autor :JORGE MOTA


// Data : 23-02-2007
// Substituir um repetir por enquanto
// Secção de Declarações
var
n,a,b,nFin: inteiro
inicio
// Secção de Comandos
escreva("Numero de elementos:")
Leia (nFin)
n <- 0
a <- 0
b <- 1
repetir
escreval(a)
escreval(b)
n <- n + 2
a <- a + b
b <- b + a
ate que (n>nFin-2)
fimalgoritmo

Pergunta 5 (3 valores)

Desenvolva um algoritmo em Raptor (fluxograma) que permita converter uma


string para maisculas e que tenham sido subtraídos os espaços a mais:

Exemplo:

114
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

esTe e um teste de algoritmia. Æ ESTE E UM TESTE DE ALGORITMIA

Nota : o underscore representa simbólicamente espaço.

Resposta:

Start

"Ler Frase -->"


GET Frase

comprimento ← Length_Of
(Frase)

Frase_P ← ""

caracter ← ""

Flag ← 0

i←1

Loop

Yes
i>comprimento

No

c ← Frase[i]

Yes No
c=32

Yes No
(Flag=1) or (i=1) Flag ← 0

Yes No
(c>=97) and (c<=122)
Flag ← 1 caracter[1] ← c

Frase_P ← Frase_P +
caracter[1] ← c - 32 caracter[1] ← c
caracter

Frase_P ← Frase_P + Frase_P ← Frase_P +


Flag ← 1 caracter caracter

i←i+1

PUT Frase_P¶

End

Pergunta 6 (3 valores)

115
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implemente em raptor (fluxograma) e em C um algoritmo que calcule a altura


ao solo de um passageiro durante um passeio na roda gigante a partir do
numero (inteiro) de cadeira que conta abaixo de si:

Vamos imaginar, que uma roda leva 12 cadeiras igualmente espaçadas ao


longo do seu perímetro, que o seu raio mede 10 metros e que o ponto mais
baixo atingido ao longo do percurso círcular está a 0,5 metros do solo. Sabe-se
também que uma roda demora cerca de 30 segundos a efectuar uma rotação
completa.

Com : h=10.sen(α), t pertencente ao intervalo fechado de [0,30].

Resolução:

Vamos considerar que o passageiro só conta as cadeiras de um dos lados.


Assim temos o seguinte definição para o problema:

Se o número de cadeiras é 0 então o passageiro esta a 0,5 m do solo.


Se o número de cadeira é inferior a 3 então a altura aproximada é de h=10,5-
(n)*10*sen(30).
Se o número de cadeira é de 3 então a altura ao solo é de 10,5 m.
Se o número esta entre 4 e 6 (ou seja 5) então h=10,5+n*10*sen(30).
Se o número de cadeiras é de 7 então a altura é de 20,5 m ao solo.

116
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Pergunta 7 (2 Valores)

Implemente iterativamente em fluxograma o seguinte seguinte algoritmo


(função) de cálculo de um factorial:

funcao factorial (v: inteiro): inteiro

inicio
se v <= 2 entao

retorne v

senao
retorne v * factorial(v-1)

fimse
fimfuncao

Resposta:

Implementação em Fluxograma:

117
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Start

n ← 10

factorial

End

Esta função é chamada com um parametro n, do tipo inteiro que


Start representa o numero que se pretende calcular o factorial.

f←1

i←n

Loop

Yes
i<1

No

f←f*i

i←i-1

PUT "Factorial de"+n+" =


"+f¶

End

118
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Implementação em Linguagem C

#include "stdio.h"
int factorial(int n);
main()
{
int valor;
valor=factorial(10);
printf("O factorial de 10=%d\n",valor);
}
int factorial(int n)
{
int i,f;
f=1;
for(i=n;i>=1;--i)
{
f=f*i;
}
return f;
}

Pergunta 8 (3 Valores)

Explique o algoritmo de ordenação Insertion Sort, implemente o mesmo em


raptor (Fluxograma) para uma ordenação crescente, partindo do princípio que a
lista a ordenar está contida num array de nome LISTA e que tem n elementos.

Resposta:

Insertion sort, ou ordenação por inserção, é um algoritmo simples de ordenação,


eficiente quando aplicado a um pequeno número de elementos. Em termos gerais, o que
faz é percorrer um vector de elementos da esquerda para a direita e à medida que avança
vai deixando os elementos mais à esquerda ordenados. O algoritmo de inserção
funciona da mesma maneira como muitas pessoas ordenam cartas num jogo de cartas
como o poquer.

119
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

120
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Anexo : Resolução da parte prática da frequência e exame de


Janeiro/Fevereiro 2007

Engenharia Informática 1º Ano - 1º Semestre


Introdução a Ciência dos Resolução parte prática da
Computadores – 1º Ano Frequência e exame.
Data : 5-02-2007 Duração : 60 Minutos
Parte Prática Prof. : Jorge Mota

Numero : Nome :

Pergunta 1

Implemente em linguagem Visual Raptor( ou em Fluxograma tradicional) e em


linguagem C um algoritmo que permita estimar o valor do integral de uma
função simples f(x) exemplo: 3x 2 − 2 x , no intervalo (1,3) usando técnica de
integração de Monte Carlo.
Notas para a implementação: ver descrição da técnica em abaixo.

121
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

8.1.8 Formulas Importantes:

8.1.9 Área Total = M*(xEsquerda-xDireita)

8.1.10 A área abaixo de f(x) = Pr(Yaleatório<=f(Xaleatório))*M*(xDireita-xEsquerda)

8.1.11 Descrição dos termos da formula:

8.1.12 M = um valor y tal que M>=f(x) para todos os XEsquerda<=X>=Xdireita)

8.1.13 Yaleatório = Um Y aleatório escolhido de forma que 0<=Yaleatório<=M

8.1.14 Xaleatório = UmX aleatório de forma que xEsquerda<=Xaleatório<=xDireita

8.1.15 F(Xaleatório)=f(x) calculado no ponto Xaleatório

8.1.16 Pr(Yaleatório<=f(Xaleatório))= Probabilidade aleatória de o ponto estar abaixo de f(x)

A técnica de integração de Monte Carlo baseia-se na estimativa obtida pela teoria das
probabilidades. Dado um intervalo (xEsquerda, xDireita) de uma função, f(x) que está
limitada por uma constante M, o método de Monte Carlo aleatoriamente selecciona pontos
dentro da “caixa” de restrições horizontal (intervalo de integração) e vertical (constante M)
e determina se o ponto fica acima ou a baixo da função. A probabilidade de que o ponto
esteja abaixo de f(x) é igual, na proporção da “caixa” de restrição, à probabilidade de estar
acima de f(x). Quantos mais pontos forem escolhidos mais precisa a estimativa e portanto
mais precisa a área final estimada.

Resposta
8.1.17

8.1.18 1) Especificar quantos numeros vão ser utilizados – n. No nosso caso vamos usar
1024.
2) Qual a função a usar. No nosso caso 3 x − 2 x
2

3) Qual o valor de M, que deve ser maior que o maior valor da função para o intervalo de
integração.No nosso caso vamos usar 21.

8.1.19 4) Gerar numeros aleatórios na caixa de restrições que é imposta por: no eixo dos xx
[ xEsquerda,xDireita] e em y por [0,21]

rx=(xDireita-xEsquerda)* random/(LONG_MAX))+xEsquerda
ry=M*random()/(LONG_MAX)

A constante LONG_MAX representa o máximo numero que pode ser gerado


pelo random em raptor será igual a 1 e em gcc por exemplo está
definida em limits.h

5)Iterar os 1024 pontos gerados aleatóriamente. No nosso caso


implementado por um ciclo contado tendo o cuidado de para cada x e y
gerado calcular o valor da função F(x) e verificar se é inferior ao Y
gerado. No caso de ser incrementar o contador de pontos que depois nos
irá permitir estimar a área.

6)Finalmente calcular a area pela proporção de numeros gerados que são


inferiores a F(rx) relativamente a area da caixa de restrições.

122
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

(contagem/nPontos)*(M*(xDireita-xEsquerda))

Implementação em Raptor:

Programa principal, limita-se a inicializar variaveis e a chamar a função de cálculo pela


técnica de integração de Monte Carlo(mc) e apresentar o valor calculado.

Start

LONG_MAX ← 1

M ← 21.0

A←1

B←3

nPontos ← 1024

MC

PUT "valor do integral para


um calculo com 1024
pontos="+area¶

End

123
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Função que implementa o calculo do integral pela técnica de integraçãode Monte Carlo
(mc):

124
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

125
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Finalmente o subprograma que implementa a função a integrar (Hardcoded):

Start

f_y ← 3 * x * x - 2 * x

End

Implementação em Linguagem C:

/**********************************************************/
/* */
/* Autor: JM */
/* Data: 25 Janeiro, 2007 */
/* Disciplina: Introdução a Ciência dos Computadores */
/* Professor: Jorge Mota */
/* Descrição: Este programa integra uma função, embebida*/
/*No código e representada por F, no intervalo definido */
/*A a B usando a Técnica de Integração de Monte Carlo. */
/* */
/**********************************************************/

#include <math.h> /* Usar a biblioteca matemática */


#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define SEED 5

/* Formula */
/*
#define A 1.0
#define B 3.0
#define M 21.0
#define FORMULA (3 * x * x - 2 * x)
#define F_STRING "(3 * x * x - 2 * x)"
*/

/* Esta é a função matemática a ser integrada. */


/* Tem uma variável x como entrada e devolve F(x). */

double F(double x)
{
return FORMULA;
}

/* Esta função integra f entre xEsquerda e xDireita usando o método de


integração de Monte Carlo */
/* É desenhado caixa usando os valores definidos pelo intervalo
xEsquerda e xDireita e o minimo e máximo como base e topo do mesmo.

126
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

Para o valor máximo devemos estimar um valor adequado de acordo com a


gráfico da função. */

/* São gerados pontos aleatóriamente dentro desta caixa de valores e


determinado se o valor gerado se encontra acima ou abaixo da função F
*/

/* A fracção de pontos gerados abaixo da função é a mesma que a


fracção da área da caixa abaixo da função ou seja o valor do integral
da mesma no intervalo considerado. Esta consideração só é valida para
um numero significativo de pontos*/

/*ATENÇÃO estamos a considerar que a constante LONG_MAX é o máximo


valor possivel de ser gerado pela função rand(). Está sempre
dependente do compilador. Neste caso consideramos que está definida em
limits.h (gcc) */

double integrar_mc(double xEsquerda, double xDireita, double


f(double), int nPontos, double M)
{
int i; /* Variavel contadora */
int contagem=0; /* Numero de ponto de abaixo da função*/
double rx; /* valor aleatório x no intervalo de valores da caixa*/
double ry; /* valor aleatório y no intervalo de valores da caixa*/
double f_y; /*valor de y= valor da função no ponto aleatório rx*/

for (i=0; i<nPontos;++i)


{
/*Escolher um pontos aleatório na caixa de valores. Os valores
rx e ry devem escolhidos independentemente*/
rx=(xDireita-xEsquerda)* rand()/((double) (LONG_MAX))+xEsquerda);
ry=M*rand()/((double) (LONG_MAX));

/* verificar se o ponto está abaixo da função*/


f_y=F(rx);
if (ry<f_y)
contagem++;
}
return (contagem/((double)(nPontos))*(M*(xDireita-xEsquerda)));
}

/* Main() é responsável por chamar o método que calcula a integração*/


/* e imprimir a area calculada */

int main(void)
{
int n; /* numero de pontos */
double mc; /* area estimada pela técnica de Monte Carlo */

srand(SEED);

printf("\n");
printf("Integrar F(x) = %s de %5.3f to %5.3f\n", F_STRING, A, B);
printf("\n");

n=1024;
printf("n = %d\n", n);

127
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

mc = integrar_mc(A, B, F, n,M);
printf("Método Monte Carlo: Area com n pontos = %9.6f\n", mc);

return 0;
}

Esta pergunta vale 20 valores em 20.

Critérios para correcção:

Se o aluno consegue descrever em português corrente os passos do algoritmo 10%

Se aluno estrutura convenientemente o algoritmo em funções(Métodos e Constantes) 10%

Se o aluno comenta correcta e completamente o código 10%

Se o aluno consegue especificar a forma de calculo dos numeros gerados aleatóriamente na


caixa de restrições 10%

Se o aluno define o algoritmo de integração correctamente, separando convenientemente


variáveis, ciclo de calculo acumulado da área e impressão formatada do output em Raptor 20%

Se o aluno define o algoritmo de integração correctamente, separando convenientemente


variáveis, ciclo de calculo acumulado da área e impressão formatada do output em C 20%

Se o Nome das variaveis está adequado a sua função e não gera confusão com nomes
reservados 5%

Se o algoritmo em Raptor funciona sem erros 10%

Se o algoritmo em C funciona Correctamente 5%

128
Apontamentos de Apoio às aulas de Algoritmia do Professor Jorge Mota 2006

9 Bibliografia

[1] Rocha, António Adrego da, Introdução à Programação usando C ,


(FCA, 2006).

[2] Schildt, Herbert, C Completo e Total, (Osborne, 1997).

[3] Standish, Thomas A, Algorithms and Software Principles, (Addison-


Wesley, 1995).

[4] Souza, Cláudio Morgado, Manual do VisualAlg v2, (2006).

[5] http://www.apoioinformatica.inf.br/

129

Você também pode gostar