Вы находитесь на странице: 1из 51

Algoritmos

Técnicas de Programação
José Augusto N. G. Manzano
Ecivaldo Matos
André Evandro Lourenço

Algoritmos
Técnicas de Programação

1ª Edição

www.editoraerica.com.br

1
Dados Internacionais de Catalogação na Publicação (CIP)
(Câmara Brasileira do Livro, SP, Brasil)

Manzano, José Augusto N. G.


Algoritmos : técnicas de programação / José Augusto N. G. Manzano, Ecivaldo Matos,
André Evandro Lourenço. -- 1. ed. -- São Paulo : Érica, 2014.

Bibliografia
ISBN 978-85-365-0737-8

1. Algoritmos 2. Linguagens de programação (Computadores) 3. Programação (Computadores eletrônicos) I. Matos,


Ecivaldo. II. Lourenço, André Evandro. III. Título.

14-01498 CDD-005.1

Índices para catálogo sistemático:


1. Algoritmos : Computadores : Programação : Processamento de dados 005.1

Copyright © 2014 da Editora Érica Ltda.


Todos os direitos reservados. Nenhuma parte desta publicação poderá ser reproduzida por qualquer meio ou forma sem prévia autorização
da Editora Érica. A violação dos direitos autorais é crime estabelecido na Lei nº 9.610/98 e punido pelo Artigo 184 do Código Penal.

Coordenação Editorial: Rosana Arruda da Silva


Capa: Maurício S. de França
Preparação e Edição de Texto: Beatriz M. Carneiro, Bruna Gomes Cordeiro, Carla de Oliveira Morais Tureta,
Juliana Ferreira Favoretto, Nathalia Ferrarezi, Silvia Campos
Produção Editorial: Adriana Aguiar Santoro, Alline Bullara, Dalete Oliveira, Graziele Liborni, Laudemir Marinho dos
Santos, Rosana Aparecida Alves dos Santos, Rosemeire Cavalheiro
Editoração: ERJ Composição Editorial

Os Autores e a Editora acreditam que todas as informações aqui apresentadas estão corretas e podem ser utilizadas para qualquer m legal.
Entretanto, não existe qualquer garantia, explícita ou implícita, de que o uso de tais informações conduzirá sempre ao resultado desejado.
Os nomes de sites e empresas, porventura mencionados, foram utilizados apenas para ilustrar os exemplos, não tendo vínculo nenhum com
o livro, não garantindo a sua existência nem divulgação. Eventuais erratas estarão disponíveis para download no site da Editora Érica.
Conteúdo adaptado ao Novo Acordo Ortográco da Língua Portuguesa, em execução desde 1º de janeiro de 2009.
A ilustração de capa e algumas imagens de miolo foram retiradas de <www.shutterstock.com>, empresa com a qual se mantém contrato
ativo na data de publicação do livro. Outras foram obtidas da Coleção MasterClips/MasterPhotos© da IMSI, 100 Rowland Way, 3rd oor
Novato, CA 94945, USA, e do CorelDRAW X5 e X6, Corel Gallery e Corel Corporation Samples. Copyright© 2013 Editora Érica, Corel
Corporation e seus licenciadores. Todos os direitos reservados.
Todos os esforços foram feitos para creditar devidamente os detentores dos direitos das imagens utilizadas neste livro. Eventuais omissões
de crédito e copyright não são intencionais e serão devidamente solucionadas nas próximas edições, bastando que seus proprietários conta-
tem os editores.

Seu cadastro é muito importante para nós


Ao preencher e remeter a cha de cadastro constante no site da Editora Érica, você passará a receber informações sobre nossos lançamentos
em sua área de preferência.
Conhecendo melhor os leitores e suas preferências, vamos produzir títulos que atendam suas necessidades.

Contato com o editorial: editorial@editoraerica.com.br

Editora Érica Ltda. | Uma Empresa do Grupo Saraiva


Rua São Gil, 159 - Tatuapé
CEP: 03401-030 - São Paulo - SP
Fone: (11) 2295-3066 - Fax: (11) 2097-4060
www.editoraerica.com.br

2 Algoritmos - Técnicas de Programação


Agradecimentos

Agradecemos a todos aqueles que acreditam na educação como um dos elementos undamen-
tais para a mudança social.

3
Sobre os autores

José Augusto N. G. Manzano, brasileiro, nascido em São Paulo, em 26 de abril de 1965,


é proessor e mestre com licenciatura em Matemática. Atua na área de ecnologia da Inorma-
ção (desenvolvimento de sofware, ensino e treinamento) desde 1986. Participou do desenvol-
vimento de aplicações computacionais para as áreas de telecomunicações e comércio. Na carreira
docente, iniciou sua atividade em cursos livres, trabalhando posteriormente em empresas de trei-
namento e atuando nos ensinos técnico e superior. rabalhou em empresas da área, como: ABAK,
SERVIMEC, CEBEL, SPCI, BEPE, ORIGIN, OpenClass, entre outras.
Atualmente, é proessor com dedicação exclusiva ao IFSP (Instituto Federal de Educação,
Ciência e ecnologia de São Paulo, antiga Escola écnica Federal). Em sua carreira como docente,
tem condições de ministrar componentes curriculares de Lógica de Programação (Algoritmos),
Estrutura de Dados, Microinormática, Inormática, Linguagens de Programação Estruturada, Lin-
guagens de Programação Orientada a Objetos, Engenharia de Sofware, ópicos Avançados em Pro-
cessamento de Dados, Sistemas de Inormação, Engenharia da Inormação, Arquitetura de Compu-
tadores e ecnologias Web. Possui conhecimento de uso e aplicação das linguagens de programação
CLASSICBASIC, COMAL, Assembly, LOGO, PASCAL, FORRAN, C, C++, JAVA, MODULA-2,
SRUCUREDBASIC, C#, Lua, HML, XHML, JavaScript, VBA e ADA. Possui mais de oitenta
obras publicadas, além de artigos publicados no Brasil e no exterior.
Ecivaldo Matos, doutor em Educação (Didática, eorias de Ensino e Práticas Escolares) pela
Faculdade de Educação da Universidade de São Paulo (USP), com apoio do Programa Internacional
de Bolsas de Pós-graduação da Fundação FORD (IFP - Ford Foundation International Fellowships
Program), mestre em Inormática pela Universidade Federal de Campina Grande e bacharel em
Ciência da Computação com especialização em Sistemas Distribuídos pela Universidade Federal da
Bahia. Atuou como proessor eetivo do Colégio Pedro II (RJ), na área de Ciência da Computação e
como pesquisador do Laboratório de Estudos da Aprendizagem Humana da Universidade do Estado
do Rio de Janeiro (LEAH/UERJ). Atualmente, é proessor e coordenador da área de Inormática do
Instituto Federal de Educação, Ciência e ecnologia de São Paulo - IFSP (Campus São Paulo), pes-
quisador
Comissãodo
de Grupo Alpha
Educação (USP), membro
da Sociedade da de
Brasileira Association or (SBC).
Computação Computing Machinery (ACM) e da

André Evandro Lourenço, mestre em Engenharia Elétrica (Processamento em Alto Desempe-


nho e Sistemas Digitais) pela Universidade de São Paulo (USP) e bacharel em Ciência da Compu-
tação pela Universidade Federal de Mato Grosso do Sul (UFMS). Atualmente, é proessor e coor-
denador do Instituto Federal de Educação, Ciência e ecnologia de São Paulo - IFSP (Campus São
Paulo) e docente do Centro Universitário Fundação Instituto de Ensino para Osasco (UNIFIEO).
em experiência técnica e docente nas áreas de programação em ambiente internet, data mining,
webmining, algoritmos e estruturas de dados, sistemas operacionais, arquitetura de computadores,
computação gráfica, gestão empresarial, marketing e propaganda, além de trabalhos envolvendo
banco de dados.

4 Algoritmos - Técnicas de Programação


Sumário

Capítulo 1 - Introdução aos Algoritmos ....................................................................................... 9


1.1 Breve história da computação .........................................................................................................................................9
1.2 Lógica de programação e algoritmos ...........................................................................................................................13
1.3 Paradigmas de programação .........................................................................................................................................14
1.4 Diagrama de blocos ........................................................................................................................................................15
1.5 Linguagem de projeto de programação .......................................................................................................................16
1.6 Interpretadores, compiladores e tradutores ................................................................................................................17
1.6.1 Interpretadores ......................................................................................................................................................17
1.6.2 Compiladores .........................................................................................................................................................18
1.6.3 radutores...............................................................................................................................................................18
1.7 Recomendações para resolução de problemas............................................................................................................19
1.8 abela ASCII....................................................................................................................................................................20
Agora é com você! .................................................................................................................................................................24
Capítulo 2 - Programação Sequencial ........................................................................................ 25
2.1 Etapas operacionais ........................................................................................................................................................25

2.2 ipos de dados


2.2.1 Dado ................................................................................................................................................................26
numérico inteiro .........................................................................................................................................26
2.2.2 Dado numérico real ..............................................................................................................................................26
2.2.3 Dado caractere/cadeia...........................................................................................................................................27
2.2.4 Dado lógico ............................................................................................................................................................27
2.3 Variáveis ...........................................................................................................................................................................27
2.4 Constantes .......................................................................................................................................................................28
2.5 Operadores aritméticos..................................................................................................................................................29
2.6 Expressões aritméticas ...................................................................................................................................................29
2.7 Instruções e comandos...................................................................................................................................................31
Agora é com você! .................................................................................................................................................................36
Capítulo 3 - Programação com Desvios ..................................................................................... 37
3.1 omada de decisões ........................................................................................................................................................37
3.2 Operadores relacionais...................................................................................................................................................38
3.3 Desvios condicionais ......................................................................................................................................................39
3.3.1 Desvio condicional simples .................................................................................................................................39
3.3.2 Desvio condicional composto..............................................................................................................................41
3.3.3 Desvio condicional encadeado ............................................................................................................................42
3.3.4 Desvio com múltipla escolha ...............................................................................................................................44
3.4 Divisibilidade ..................................................................................................................................................................45
3.5 Operadores lógicos .........................................................................................................................................................47
3.5.1 Operador lógico .e. ................................................................................................................................................47
3.5.2 Operador lógico .ou. .............................................................................................................................................48
3.5.3 Operador lógico .não. ...........................................................................................................................................50
Agora é com você! .................................................................................................................................................................52

5
w
a
h
lis
w
o
e
C
ik
M
/
s
n
o
m
m
o
C
a
i
d
e
m
i
k
i
W

Figura 1.1 - Ábaco.

Somente em 1642, o rancês Blaise Pascal cria uma máquina com capacidade para realizar
somas e subtração de orma automática. Essa máquina, batizada de Pascalina, simulava por meio de
rodas dentadas o uncionamento do ábaco. Alguns anos depois, em 1672, Gottried Wilhelm Leibniz
consegue modificar a máquina de Pascal com o objetivo de incluir operações de multiplicar e dividir.

2
1
5
m
u
ie
T
/
s
n
o
m
m
o
C
ia
d
e
im
ik
W

Figura 1.2 - Máquina de somar e subtrair de Pascal.

Diversas máquinas oram criadas ao longo do tempo por diversos inventores. O objetivo das
máquinas sempre oi auxiliar em cálculos complexos ou substituir o homem em alguma atividade.
Entre as diversas máquinas que oram criadas, temos: máquina de tear (1804), de Joseph Marie
Jacquard; máquina de dierenças (1822); máquina analítica, (1837) de Charles Babbage; e máquina

de Hollerith (1890), de Hermann Hollerith.

10 Algoritmos - Técnicas de Programação


e
lin
n
O
e
rg
o
e
G
/
s
n
o
m
m
o
C
ia
d
e
im
ik
W

Figura 1.3 - Máquina de tear de Joseph Marie Jacquard.

)
B
y
(B
l
a
rr
a
B
o
n
ru
B
/
s
n
o
m
m
o
C
ia
d
e
im
ik
W

Figura 1.4 - Máquina de dierenças e máquina analítica de Charles Babbage.

Introdução aos Algoritmos 11


e
in
h
c
a
M
s
u
s
n
e
C
/
s
n
o
m
m
o
C
ia
d
e
im
ik
W

Figura 1.5 - Máquina de Hermann Hollerith.

odas as máquinas criadas até então eram dispositivos mecânicos e não utilizavam nenhum
tipo de circuito elétrico.
A utilização de circuitos elétricos só oi possível depois que um matemático chamado George
Boole criou um sistema lógico no qual tudo poderia ser representado por meio de dois algarismos:
0 ou 1. Nascia aí a Lógica Booleana, utilizada até hoje em todos os modernos computadores. Em
sua teoria, 0 (zero) representa algo que esteja desligado, apagado, sem valor. Já o valor 1 (um) repre-
senta ligado, aceso. Com a combinação desses algarismos, podemos criar outros valores. Vejamos
um exemplo que utilize 2 algarismos:
00 - Apagado
01 - Luz verde
10 - Luz amarela
11 - Luz vermelha

Fique de olho!
Para cada algarismo utilizado, damos o nome debit. No exemplo acima, temos dois bits. Para construir os símbolos uti-
lizados em nosso alfabeto (letras e números) utilizamos oito algarismos, ou seja, oito bits. Para um conjunto de oitobits
damos o nome de byte. Portanto, para formar uma letra ou número do nosso alfabeto, utilizamos um byte.
1 byte = 8 bits

12 Algoritmos - Técnicas de Programação


» Vantagens
Correções e alterações são realizadas mais rapidamente.
Consome menos memória.
» Desvantagens
Execução mais lenta (necessidade de interprestar comando por comando).
Necessidade de sempre ler o código srcinal (código-onte) para que ele seja executado.
Exemplos: Javascript, Lua, Ruby, PHP etc.

1.6.2 Compiladores
Um compilador trabalha de orma semelhante ao interpretador, porém, ao final do processo de
conversão, é gerado um arquivo chamado código executável (programa executável). O código execu-
tável é um arquivo binário que será executado diretamente pela máquina sem a necessidade de inter-
pretação linha a linha.
» Vantagens
É executado de orma mais rápida e diretamente ao nível de máquina.
»

Desvantagens
A manutenção só é possível a partir do código-onte.
O código executável gerado só poderá ser executado em máquinas de mesma arquitetura.
Exemplos: C, C++, C#, Pascal etc.

1.6.3 Tradutores
Existe um terceiro método que trabalha de orma intermediária entre os compiladores e inter-
pretadores. Umtradutor gera, a partir do código-onte, um código intermediário, mas que não exige
tanto espaço de memória quanto o código srcinal. É gerado, a partir do código intermediário, o
código executável da orma que um interpretador unciona.
» Vantagens
Independência da arquitetura que ará a execução final.
» Desvantagens
Necessidade de um interpretador específico na máquina do usuário final que ará a inter-
pretação.
Exemplo: Java

18 Algoritmos - Técnicas de Programação


A equipe de desenvolvimento deverá escolher entre os diversos tipos de erramentas de pro-
gramação, ou linguagens de programação, disponíveis no mercado, levando em consideração diver-
sos atores como hardware, sistema operacional, velocidade de execução, limitação tecnológica etc.

1.7 Recomendações para resolução de problemas


A construção de algoritmos requer tempo e paciência, porém, em diversas literaturas, são cita-
das algumas
grama técnicas
de blocos, que que acilitama construção
irá orientar e aceleram esse processo.e,Antes
do algoritmo de começar
por fim, a desenhar
a elaboração o dia-
do programa,
deve-se ficar atento ao problema a ser resolvido, ou seja, ao objetivo a ser alcançado, que é o que o
programa deverá gerar de saída. ambém deve-se pensar em quais dados serão necessários para
o processamento, em como esses dados serão processados e em quais cálculos devem ser criados.
Observe, a seguir, quatro regras simples para a construção dos diagramas de blocos de orma
correta:
1) Níveis: divida os diagramas de blocos em vários níveis. Os primeiros devem conter apenas
as ideias principais e não os detalhes. Deixe o refinamento para as etapas seguintes.
2) De cima para baixo: uma boa prática é sempre construir os blocos de cima para baixo.
3) Não cruzar linhas: evite e, se possível, nunca cruze as linhas de fluxo de dados nos diagra-
mas de bloco.
4) Português estruturado: assim que os diagramas de blocos orem concluídos, transcreva
para o português estruturado.

Exercício resolvido
Um uncionário recebe determinado salário mensal. Faça um programa que leia o valor do
salário mensal e o índice (em porcentagem) do reajuste a ser concedido. O programa deverá
imprimir na tela o novo salário do uncionário.

Solução
Em primeiro lugar, devemos entender o principal problema a ser resolvido. Nesse caso, calcu-
lar o valor do novo salário.
A segunda etapa apresenta um detalhamento no que se reere à entrada e saída, ou seja, deve-
-se entrar com o valor do salário atual e com o índice do reajuste para que, após o cálculo, seja
exibido o valor do novo salário.

Introdução aos Algoritmos 19


Exercício resolvido
Na terceira etapa, vamos trabalhar o processo de gerar o cálculo do novo salário, introduzin-
do o conceito de variáveis (você verá mais sobre isso nos próximos capítulos). Serão digitados
dois valores, um para o salário atual e outro para o índice de reajuste (em porcentagem). Com
esses dados, será calculado o novo salário. Sendo assim, temos a Figura 1.9.

Início

SALÁRIO, ÍNDICE

novoSalário salário + salário índice/100

novoSalário

Fim

Figura 1.9 - Diagrama de bloco nível 2 para o cálculo do novo salário.

Você viu, na Figura 1.10, a primeira orma de notação gráfica. Agora, iremos transcrever o dia-
grama de blocos para uma orma narrativa denominada pseudocódigo ou português estruturado.
O português estruturado se aproxima muito da linguagem (por exemplo, PASCAL, C,
FORRAN, BASIC, JAVA, PHP etc.) utilizada pelos computadores para gerarem o programa a
ser executado, porém, não tem o mesmo rigor sintático de sua escrita.
A seguir, é apresentado um exemplo do algoritmo escrito em português estruturado.
programa SALARIO

var

SALÁRIO, ÍNDICE, NOVOSALÁRIO: real


inicio

leia SALÁRIO, ÍNDICE

NOVOSALÁRIO ← SALÁRIO + SALÁRIO * ÍNDICE / 100


escreva NOVOSALÁRIO

m

1.8 Tabela ASCII


A tabela ASCII (pronúncia é “asqui”), ouAmerican Standard Code or Inormation Interchange
(Código Americano Padrão para Intercâmbio de Inormações), é composta por 256 símbolos, que são
utilizados pelos computadores eletrônicos. Foi criada entre os anos de 1963 e 1968 com participação e

20 Algoritmos - Técnicas de Programação


Programação
com Desvios 3
Para começar

O objetivo principal deste capítulo é o estudo dos mecanismos para que possamos eetuar uma
tomada de decisão simples, composta ou encadeada, por meio do processamento lógico. Para que
uma tomada de decisão seja eetuada pela máquina, destacamos, também, operadores lógicos e relacionais.

3.1 Tomada de decisões

da se Na construçãocondição
determinada de algoritmos, muitas Essa
or satiseita. vezescondição
é necessário que uma
é definida parte
por umadoexpressão
código sólógica
seja executa-
cujo
resultado sempre será um valor also ou verdadeiro. A expressão lógica, que testará as condições
impostas pelo algoritmo, utiliza uma relação entre um par de elementos, o qual pode ser composto por
variável versus variável ou variável versus constante, e um operador relacional (apresentado no pró-
ximo tópico).
Ao desenvolver os diagramas de blocos, deve-se utilizar os símbolos de decisão e conexão,
conorme a Figura 3.1.

Figura 3.1 - Símbolos de decisão e conexão, necessários ao desenvolvimento de diagramas de blocos.

37
Amplie seus conhecimentos
ocê sabia que o ENIAC (Electronic Numerical Integrator and Computer) é considerado o primeiro computador eletrônico
digital? Foi construído entre 1943 e 1945, entrando em operação em julho de 1946 com a finalidade de ser usado em
cálculos de balística. Para seu funcionamento havia 17.468 válvulas, 1.500 relés, além de diversos outros componentes
eletrônicos, pesando 30 toneladas! Os técnicos que o operavam trabalhavam dentro do computador.
ara saber um pouco mais, consulte: <http://www.hardware.com.br/guias/historia-informatica/eniac.html>. Acesso em:
28 jan. 2014.

3.2 Operadores relacionais


Um operador relacional é utilizado para comparar a relação entre pares de valores definidos
por variáveis ou constantes. Sempre deve existir um par de valores para determinar se a condição é
verdadeira ou alsa.
Pela análise dos operadores relacionais, um computador consegue determinar as ações a serem
tomadas pela máquina. A abela 3.1 apresenta os operadores relacionais utilizados na programação
de computadores.
abela 3.1 - Operadores relacionais
Operador Descrição
= Iguala
> Maiorque
< Menorque
>= Maior ou igual a
<= Menor ou igual a
<> Diferentede

Veja exemplos de operações válidas entre variáveis e constantes:


A = B; A > B; A < B; A >= B; A <= B; A <> B; A = 2; A > 2; A < 2; A >= 2; A <= 2; A <> 2
Observe que sempre deve existir um par de valores para a devida validação.
Exemplos de operações NÃO válidas:
A = B = C ou A > 5 > 2
odos os operadores relacionais possuem o mesmo nível de precedência, portanto não há
necessidade de se preocupar em alterá-lo.

38 Algoritmos - Técnicas de Programação


3.3 Desvios condicionais
Com os conhecimentos adquiridos nos capítulos anteriores, já temos condições de resolver
diversos tipos de problemas que envolvam entradas de dados, processamentos e saídas com a utilização
de variáveis, constantes e operadores aritméticos. Em diversos casos, porém, para que o proces-
samento seja mais adequado, a máquina deverá decidir quais trechos de código serão ou não execu-
tados, por meio dos desvios condicionais.

Basicamente, há três modos de desvio condicional: simples, composto e seletivo.

3.3.1 Desvio condicional simples


Em um desvio condicional simples, determinado bloco só será executado se a condição
imposta or verdadeira; caso contrário, todo o bloco será ignorado. No caso, utilizaremos a instru-
ção: se...então...fim_se.
No diagrama de blocos da Figura 3.2, observe que a letra S representa sim, a fim de mostrar
o fluxo de execução quando a condição or verdadeira. Já a letra N representa não e será executada
quando a condição or alsa. Quando a condição or alsa, note que nada será executado. O símbolo
de decisão deve ser utilizado quando houver a necessidade de tomar uma decisão no programa.

Diagrama de blocos

N S
Condição

Bloco de comandos que


só será executado quando
a condição for verdadeira

Bloco de comandos que


sempre será executado

Figura 3.2 - Estrutura do símbolo para a instrução se...então...fim_se.

Português estruturado

se (<condição>) então

<Bloco de comandos que só será executado quando a condição for verdadeira>

m_se
<bloco de comandos que sempre será executado>

Programação com Desvios 39


Exemplo
Construir um programa que aça a leitura de dois números reais e imprima na tela a média arit-
mética simples. Se a média or maior ou igual a 7.0, deve imprimir também a palavra “aprovado”.
Solução
Para este exercício, precisamos definir apenas três variáveis reais, ou seja, numero1, numero2 e
media. Após calcular e imprimir a média, devemos testar, por meio de desvio condicional sim-
ples, se a média é maior ou igual a 7.0, imprimindo a mensagem “aprovado”.
Diagrama de blocos
INÍCIO

NUMERO1, NUMERO2

(NUMERO
1+ NUMERO
2)/2

MEDIA

N S
MEDIA >= 7

‘‘APROVADO’’

FIM

Figura 3.3 - Exemplo de utilização da estrutura se...então...fim_se.


Português estruturado
programa MEDIA

var

NUMERO1, NUMERO2, MEDIA : real


início

leia NUMERO1
leia NUMERO2

MEDIA ← (NUMERO1 + NUMERO2)/ 2


escreva MEDIA

se (MEDIA > 7) então


escreva "aprovado"

 m_ se
m

40 Algoritmos - Técnicas de Programação


3.3.2 Desvio condicional composto
Em um desvio condicional composto, é possível determinar o bloco a ser executado para uma
condição verdadeira e o bloco a ser executado para uma condição alsa. No caso, utilizaremos a ins-
trução: se...então...senão...fim_se.

Diagrama de blocos

N S
Condição

Bloco de comandos que Bloco de comandos que


só será executado quando só será executado quando
a condição for falsa a condição for verdadeira

Bloco de comandos que


sempre será executado

Figura 3.4 - Diagrama de blocos para a instrução se...então...senão...fim_se.

Português estruturado

se (<condição>) então

<instruções para condição verdadeira>


senão

<instruções para condição falsa>


 m_se

Exemplo
Construir um algoritmo que leia dois números reais e calcule a média aritmética desses núme-
ros. O programa deve imprimir APROVADO se a média or maior ou igual a 7.0; caso contrá-
rio, deve imprimir REPROVADO.
Solução
Para este exemplo, tomaremos como base o exemplo anterior, em que não é possível optar por
imprimir APROVADO, se a média or superior ou igual a 7, ou, do contrário, REPROVADO.
Note que devemos utilizar, aqui, o SENÃO.

Programação com Desvios 41


se(<condição 1>) então

se(<condição 2>) então

<ação executada quando condição 1 e condição 2 forem verdadeiras>


senão

<ação executada quando condição 1 for verdadeira e condição 2 for falsa>


m_se
senão

<ação executada quando condição 1 for falsa>


m_se

3.3.4 Desvio com múltipla escolha


Nos casos em que se tem uma mesma condição, porém com múltiplos valores, a estrutura
se...senão se... seria muito grande, portanto cansativa de se construir. Nesses casos, é recomendado
construir o algoritmo utilizando a estrutura de desvio com múltipla escolha. Como restrição, a
condição só aceita o operador relacional de igualdade; na construção da instrução, utilizaremos os
comandos caso/seja...aça/senão/fim_caso.

Diagrama de blocos

Bloco de comandos que


S
Condição 1 só será executado quando a
condição 1 for verdadeira

N
Bloco de comandos que
S
Condição 2 só será executado quando a
condição 2 for verdadeira

S Bloco de comandos que


Condição 3 só será executado quando a
condição 3 for verdadeira

Bloco de comandos que só


será executado quando todas
as condições forem falsas

Bloco de comandos que


sempre será executado

Figura 3.8 - Estrutura de tomada de decisão por seleção.

44 Algoritmos - Técnicas de Programação


Português estruturado

caso <variável>
seja <opção 1> faça

[ação para condição 1 verdadeira]


seja <opção 2> faça

[ação para condição 2 verdadeira]


seja <opção 3> faça

[ação para condição 3 verdadeira]


senão

[ação para nenhuma condição satisfeita]


 m_caso

3.4 Divisibilidade
Vamos ver agora um assunto que com certeza já é conhecido dos primeiros anos do ensino
1. Operações aritmé-
básico, que são operações aritméticas de divisão realizadas com números naturais
ticas de divisão com números naturais são aquelasque possuem valor de resto com quociente inteiro.
A Figura 3.10 nos apresenta os passos da divisão do número natural 5 com o número natural 2,
que dá como resultado um quociente igual a 2 e um valor de resto igual a 1.
52 52 5 2
2 2 x

Dividendo
Divisor

5 2
5 2 5 2 -4 2
4 2 -4 2
1
1 Quociente
Resto

Figura 3.11 - Exemplo de divisão de dois números naturais.

A Figura 3.11 nos mostra que para obter o valor do resto, devemos azer a subtração do valor
do quociente multiplicado pelo divisor sob o valor do dividendo. Assim, devemos usar a expressão
Resto = Dividendo – Divisor ⋅ Quociente, que, computacionalmente, pode ser escrita como sendo:
Resto ← Dividendo – Divisor * (Dividendo div Divisor), onde o operador aritmético div az o cál-
culo de divisão com quociente inteiro.

Exemplo
Desenvolver um programa de computador que leia um valor numérico inteiro e mostre men-
sagem inormando se o número lido é par ou ímpar.

1 Números naturais são ormados pelo conjunto de todos os números inteiros positivos, incluindo-se zero e representado pela letra
N maiúscula, sendo: N = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ... }.

Programação com Desvios 45


Solução
Para resolver este problema, é necessário verificar se a condição do valor lido é ou não divisível
por 2. Para tanto, leia um valor numérico inteiro qualquer (variável N), calcule o resto da divi-
são de N por 2 (variável R) e verifique se a variável R possui o valor de resto igual a zero e, se
sim, apresentar a mensagem “Valor par”; caso contrário, mostrar a mensagem “Valor impar”.

Diagrama de blocos
INÍCIO

RESTO N-2 (N DIV 2)

N S
RESTO = 0

‘‘VALOR ‘‘VALOR
IMPAR’’ PAR’’

FIM

Figura 3.12 - Diagrama de blocos para verificar se N é par ou ímpar.

Português estruturado

programa PAR_OU_IMPAR
var

N, RESTO : inteiro
início

leia N
RESTO ← N - 2 * (N div 2)
se (RESTO = 0) então

escreva "Valor par"


senão

escreva "Valor impar"


m_se
m

Observe o uso da expressão RESO ← N − 2 * (N div 2), que obtém o valor de divisibili-
dade da operação de divisão entre a variável N (dividendo) e o valor 2 (divisor) gerando o valor do
RESO da divisão entre N e 2. A instrução de tomada de decisão az uso da condição (RESO = 0),
que é verdadeira se o valor de RESO or igual a zero.

46 Algoritmos - Técnicas de Programação


3.5 Operadores lógicos
Para solucionar determinados problemas, temos a necessidade de combinar várias condições
em uma instrução condicional. Nesses casos, utilizamos os operadores lógicos: .e., .ou. e .não..

3.5.1 Operador lógico .e.


Com a utilização do operador lógico .e., todas as condições da operação devem ser verdadeiras
para que o bloco de comandos seja executado. Observe a abela 3.2.
abela 3.2 - abela-verdade para o operador lógico .e.
Condição 1 Condição 2 Condição 1 .e. Condição 2
Falsa Falsa Falsa
Verdadeira Falsa Falsa
Falsa Verdadeira Falsa
Verdadeira Verdadeira Verdadeira

Diagrama de blocos

N Condição 1 S
.e.
Condição 2

Bloco de comandos que só


será executado quando a
condição for verdadeira

Bloco de comandos que


sempre será executado

Figura 3.8 - Exemplo de utilização do operador lógico .e.

Português estruturado

se (<condição1>) .e. (<condição2>) então

<instruções executadas se condição1 e condição2 verdadeiras>


m_se

Programação com Desvios 47


O operador lógico .e. permite que uma operação seja executada somente se todas as condições
em uso orem verdadeiras. Veja o exemplo a seguir:

Exemplo
Construir um algoritmo que leia dois valores. Um valor representa a média aritmética; o outro, o
número total de altas. O programa deve imprimir APROVADO se a média or maior ou igual a

7.0 e o número
programa total de altas or inerior a20; caso contrário, deve mostrar REPROVADO.
APROVADO_REPROVADO
var
FALTAS : inteiro
MEDIA : real
início
leia FALTAS
leia MEDIA
se (MEDIA >= 7.0) .e. (FALTAS < 20) então
escreva "aprovado"
senão
escreva "reprovado"
 m_ se

m

Note que, na sentença do SE, ambas as condições devem ser verdadeiras para que seja
impresso “aprovado” na tela. Sendo assim, observe na abela 3.3 algumas simulações de digitação:
abela 3.3 - Exemplo de utilização do operador lógico .e.
M é dia Faltas Média>=7.0 Faltas<20 Condição1.e.Condição2
8.0 30 Verdadeira Falsa Falsa
5.0 15 Falsa Verdadeira Falsa
7.0 10 Verdadeira Verdadeira Verdadeira

3.5.2 Operador lógico .ou.


O operador lógico .ou. será utilizado em situações nas quais basta qualquer uma das condições
ser verdadeira para que o resultado também seja verdadeiro e, consequentemente, o bloco de instru-
ções seja executado. Na abela 3.4, veja o emprego do operador .ou. para duas condições.
abela 3.4 - abela-verdade para o operador lógico .ou.
Condição 1 Condição 2 Condição 1 .ou. Condição 2
Falsa Falsa Falsa
Verdadeira Falsa Verdadeira
Falsa Verdadeira Verdadeira
Verdadeira Verdadeira Verdadeira

48 Algoritmos - Técnicas de Programação


Diagrama de blocos

N Condição 1 S
.ou.
Condição 2

Bloco de comandos que só


será executado quando a
condição for verdadeira

Bloco de comandos que


sempre será executado

Figura 3.9 - Exemplo de utilização do operador lógico .ou.

Português estruturado

se (<condição1>) .ou. (<condição2>) então

<instruções executadas se a condição 1 for verdadeira OU a condição 2 for verdadeira>


 m_se

Veja o exemplo a seguir:

Exemplo
programa TESTE_OU

var
CODIGO: inteiro
início

leia CODIGO
se (CODIGO = 100) .ou. (CODIGO = 200) então
escreva "código válido"
senão
escreva "o código digitado está inválido"
 m_ se
m

Programação com Desvios 49


ecnicamente, costumamos chamar o laço pelo seu correspondente em língua inglesa: loop ou
looping. Os laços podem ser executados mediante uma condição predefinida pelo programador (laço
condicional) ou sem uma condição predefinida (laço incondicional).
Além disso, é importante esclarecer que, durante a execução de um laço condicional, podemos
ter operações interativas (com a intervenção do usuário) e iterativas (sem o n - sem intervenção do
usuário, apenas iteração/repetição). Os laços incondicionais permitem apenas operações iterativas.
Veremos adiante os principais comandos para controle de laço ou repetição: enquanto...açae
repita...até que,paraloops condicionais, e a instrução
para...de...até...passo...aça
, para loops incondicionais.

Amplie seus conhecimentos


odo algoritmo tem um custo de processamento associado. Para analisar esse custo, existe uma área, na Ciência da Compu-
ação, chamada Análise de Algoritmos e Otimização. Por meio de estudos nessa área é possível verificar, dentre outras infor-
ações, a complexidade do programa (por meios matemáticos), o seu tempo de execução, o espaço de memória necessário
e a robustez do programa. O laço tem papel importante no cálculo da complexidade de um algoritmo. Muitos laços podem
aumentar o nível de complexidade de processamento do programa, portanto use esse recurso com parcimônia.
ara saber mais, consulte: Complexidade de Algoritmos Série Livros Didáticos Informática – UFRGS. Vol. 13, 3. ed.
aira Vieira Toscani; Paulo A. S. Veloso. Editora Bookman, 2012.

4.2 Laço condicional pré-teste


Dentre os laços condicionais, temos aqueles que eetuam o teste condicional antes de executar
a rotina de loop (laço condicional pré-teste) e aqueles que executam a rotina e, depois, o teste para
verificar se devem ou não continuar executando o laço (laço condicional pós-teste).
O laço condicional pré-teste executa um teste lógico no início do laço para confirmar se deve
ou não executar a porção de código do laço. Uma das estruturas mais conhecidas para esse tipo de
laço é enquanto...aça, que testa se a condição definida no início do loop é verdadeira. Enquanto essa
condição or verdadeira, o conjunto de instruções do loop será executado. Assim que a condição se
tornar alsa, o processamento deixará o loop e seguirá o caminho de execução sequencial do pro-
grama. Vale ressaltar que, caso a condição em seu primeiro teste seja alsa, as instruções internas ao
laço jamais serão executadas.
Verifique, na Figura 4.1, um exemplo de uncionamento da estrutura de controle enquanto...
aça por meio de diagrama de blocos.
Diagrama de blocos

Teste lógico

N
Condição

Instruções a
serem executadas

Figura 4.1 - Exemplo de uncionamento da estrutura enquanto...aça.

54 Algoritmos - Técnicas de Programação


Português estruturado

enquanto (<condição>) faça

<instruções a serem executadas>


 m_enquanto

Exemplo
Desenvolver um programa de computador que leia um valor inteiro qualquer, divida-o suces-
sivas vezes por 2, até que o seu valor seja menor que 5, e apresente como resultado a quantidade
de sucessivas divisões realizadas.
Solução
O programa deve possuir a variável de entrada (N) e uma segunda variável que será usada para cal-
cular a quantidade de ações (divisões sucessivas) realizadas. A variável R será iniciada com valor 0
e, a cada iteração, deverá ser acrescida de 1.
Diagrama de blocos Português estruturado
Início programa DIVISOES_SUCESSIVAS

var
R 0 N, R : inteiro
início
N
R ← 0
leia N
N
N >= 5 enquanto (N >= 5) faça
N ← N div 2
S
R ← R + 1
N Ndiv2
 m_en quan to

R R+1
escreva R
m

Fim

Figura 4.2 - Exemplo de uso da estrutura enquanto...aça.

No exemplo, utilizamos a variável R para dois propósitos: guardar o resultado final a ser exi-
bido e servir de contador. O laço apresentado eetua um pré-teste antes de permitir a execução da
rotina associada à repetição: N >= 5. Isso significa que, se o valor de N or inerior a 5, as instruções
subordinadas ao laço não serão (mais) executadas.
Ao entrar no laço, o valor de N é alterado por 2 peladivisão inteira (div). Repare que o processa-
mento está sendo realizado e o valor da variável de entrada é alterado por esse processamento. Não oi
necessário criar outra variável para guardar o cálculo. Logo em seguida, e ainda dentro do laço, o valor
do contador é alterado. Isso se repetirá até que o valor de N se torne menor que 5. Quando isso aconte-
cer, o laço será interrompido e o valor docontador, apresentado como saída doprograma.

Programação com Laços 55


Vimos, no exemplo, o uso de um laço pré-teste condicional iterativo. Vejamos, agora, outro
exemplo, mas com uma situação interativa, ou seja, com intervenção do usuário no laço.

Exemplo
Desenvolver um programa de computa- Solução
dor que leia as avaliações de consumidores
O programa deve possuir, além da variável
sobre determinado produto. Essas avaliações
são valores reais entre 5 e 10. Calcule a nota de
paraentrada (N),osuma
acumular segunda
valores lidosvariável (R)
e uma ter-
média atribuída ao produto. O usuário digi-
ceira variável (CON) para contar quantos
tará quantas avaliações considerar necessário,
valores já oram lidos. É o valor lido a cada
até que o valor digitado seja inválido (menor
iteração que será acrescido à variável R.
que 5 ou maior que 10).
A variável CON será iniciada com valor
Diagrama de blocos 0 e, a cada leitura dierente de 0, deve ser
acrescida de 1.
Início
Português estruturado
R 0
programa LACO_INTERATIVO
var
CONT 0

N, R : real
CONT : inteiro
N
início
R ← 0
N CONT ← 0
N >= 5
.e. leia N
N <= 10
enquanto (N >= 5) .e. (N <= 10) faça
S R ← R + N
R R+N
CONT ← CONT + 1
leia N
 m_en quan to
CONT CONT+ 1
se (CONT > 0) então
R ← R / CONT
N
escreva R
m

S N
CONT > 0

R R/ CONT

Fim

Figura 4.3 - Exemplo de laço controlado pelo usuário.

56 Algoritmos - Técnicas de Programação


odo o trecho de instruções compreendido entre os comandos repita e até que será repetido
enquanto a condição (I > 5) or alsa, ou seja, só deixará de ser executado quando I <= 5. Para que
essa condição se torne alsa, é imprescindível que o valor de I seja alterado (aumentado) ao longo
das iterações. Se isso não acontecer, o laço pode ser executado “infinitamente”, causando o trava-
mento do programa.
A seguir, veja um exemplo em que não se utiliza o contador como orma de controlar quantas
vezes uma rotina é executada em uma estrutura de repetição. Considere que o usuário pode encerrar
o processamento quando desejar.

Exemplo
Desenvolver um programa de computador que leia um número inteiro qualquer, eleve-o ao
quadrado e apresente o resultado do cálculo. Essa operação deve ocorrer até que o usuário res-
ponda SIM à pergunta “Deseja encerrar cálculo?”.
Solução
O programa deve possuir, além das variáveis de entrada (N) e de processamento do cálculo (R)
solicitado, uma terceira variável que será usada para guardar a resposta do usuário (ENCER).
A variável
SIM, ENCERrepetirá
o programa é iniciada comque
o laço, valor NÃOserá
somente e, cada vez que a resposta
interrompido quando adada or dierente
resposta or SIM. de
Diagrama de blocos Português estruturado
Início programa CALCULO_INTERATIVO

var

ENCER ‘‘NÃO’’ N, R : inteiro


ENCER: cadeia
N início

ENCER ← "NÃO"
repita
R N* N
leia N
R ← N * N
‘‘Deseja
encerrar?’’ escreva R

escreva "Deseja encerrar?"

RESP leia ENCER

até que (ENCER = "SIM")


m
Não
ENC = ‘‘SIM’’

Sim

Fim

Figura 4.6 - Exemplo de laço controlado pelo usuário.

Programação com Laços 59


4.4 Laço incondicional
Até agora, vimos duas estruturas de repetição para laços condicionais: enquanto...aça e
repita...até que. Além delas, há uma que costuma acilitar o trabalho do programador; é a estrutura
de laço incondicional.
Algumas vezes, o laço não depende de uma condição explícita, mas de uma contagem de valo-
res que, ao atingirem determinado patamar, interrompem o laço. Nesse caso, o laço unciona com
base em uma
dor pode usarvariável contador,
a estrutura que controla o fluxo de iterações. Para esse tipo de laço, o programa-
para..de..até..passo..aça.
No diagrama de blocos, esse tipo de laço recebe um componente dierenciado com ormato
hexagonal: o símbolo preparation. Verifique, na Figura 4.7, um exemplo de uso do laço incondicional
com diagrama de blocos.

Diagrama de blocos

Var
Início, Fim,
Incremento

Instruções

Figura 4.7 - Exemplo de uso da estrutura para..de...até...passo...aça.

Português estruturado
para <variável> de <início> até <m> passo <incremento> faça

<instruções subordinadas>
m_para

Atenção! Observe que não houve uso de condição para a escrita desse laço; não há, portanto,
teste lógico: verifica-se, apenas, se a variável de controle já chegou ao seu limite superior/inerior.
Para exemplificar o uso do laço incondicional, considere o exemplo seguinte:

60 Algoritmos - Técnicas de Programação


Exemplo
Desenvolver um programa de computador que some os dez números naturais subsequentes de
um número N dado como entrada.
Solução
O programa deve receber como dado de entrada o valor de N, que será atribuído a uma variável
de mesmo nome.
processamento doambém
laço, serácriaremos
necessárioa criar
variável R para
outra guardar
variável, a sero chamada
resultadode
a ser exibido.
variável Para
I, o
auxiliar
cujo objetivo é auxiliar o loop, servindo de variável de controle do laço incondicional. A variável
I será inicializada com o valor N + 1 para indicar o primeiro valor subsequente a N. A cada itera-
ção (ciclo do laço), a variável auxiliar terá 1 acrescido ao seu valor, até o limite de 10.
Diagrama de blocos
Início

IN + N+1,1
10,

R R+I

Fim

Figura 4.8 - Exemplo de uso da estrutura para...de...até...passo...aça...fim_para.


Português estruturado
programa SOMA_NATURAIS
var
N, R, I : inteiro
início
leia N
para I de N + 1 até N + 10 passo 1 faça
R ← R + I
 m_para
escreva R
m

Verifique a dierença deste exemplo em relação aos demais. Neste, desde o início o programa-
dor sabia quantas iterações seriam necessárias; ele não dependia de nenhuma condição a ser veri-
ficada a cada ciclo. A variável de controle oi iniciada com o valor N + 1 e incrementada de 1 em 1

Programação com Laços 61


Considerando a ordem numérica crescente, a matriz está “desordenada”, ou seja, os dados não
estão ordenados. Repare que os elementos estão na seguinte ordem: 45, 8, 17, 5 e 2. Após a ordena-
ção, eles devem estar armazenados nesta ordem: 2, 5, 8, 17 e 45.
Para eetuar a ordenação, trocaremos os elementos de posição (permutas) até chegarmos à
ordem desejada. emos, então, a seguinte situação:
A[1] = 45 | A[2] = 8 | A[3] = 17 | A[4] = 5 | A[5] = 2

Iniciaremos o processo de troca por meio da comparação um a um, ou seja, vamos começar
pelo elemento A[1] e compará-lo com todos os demais, um por vez. Assim que encontrarmos um
elemento com valor menor que A[1], aremos uma permuta, mas continuaremos o procedimento até
que A[1] tenha sido comparado com todos os outros elementos.
Após a permuta do elemento A[1], o processo deve ser repetido para A[2]. Não será necessário
compará-lo com o novo valor de A[1] porque, após a primeira permuta, já sabemos que esse valor é
o menor de todos e, portanto, está na posição adequada. Esse processo será repetido sucessivas vezes
com os demais elementos até que tenhamos ordenado todo o conjunto.
Vamos, então, executar o algoritmo de troca no conjunto de dados da matriz A. Para iniciar,
basta comparar o valor do elemento armazenado em A[1] com o valor do elemento em A[2]. Como
oA[2],
elemento em aA[2]
deixando é menor
matriz com osque o elemento
elementos nestaem A[1], é preciso azer uma permuta entre A[1] e
ordem:
A[1] = 8 | A[2] = 45 | A[3] = 17 | A[4] = 5 | A[5] = 2
Continuaremos a comparação do valor de A[1] = 8 com o valor de A[3] = 17. Nesse caso, A[3]
não é menor que A[1], portanto não haverá troca. Seguiremos, assim, com a execução do algoritmo,
comparando o valor de A[1] com o de A[4].
O elemento em A[4] é menor que o valor em A[1], então esses elementos serão trocados, dei-
xando a matriz com a seguinte configuração:
A[1] = 5 | A[2] = 45 | A[3] = 17 | A[4] = 8 | A[5] = 2

Perceba
mais baixo, que,
mais à medida
próximo do que o algoritmo
ideal, que, nesse executa
caso, é oanúmero
ordenação,
2. o valor do primeiro elemento fica
Continuamos o processo, desta vez comparando o valor de A[1] com o de A[5]. Como A[5]
possui o valor 2, que é menor que o valor 5 armazenado em A[1], haverá permuta entre esses dois
elementos. Após essa troca, a matriz fica da seguinte orma:
A[1] = 2 | A[2] = 45 | A[3] = 17 | A[4] = 8 | A[5] = 5
Não há mais elementos a serem comparados com A[1] e, por esse motivo, já temos o valor
final esperado para o elemento A[1]. Assim, não precisamos mais eetuar comparações com o ele-
mento A[1].
A[1] = 2 | A[2] = 45 | A[3] = 17 | A[4] = 8 | A[5] = 5

Aplicação Prática de Matrizes 75


Repetiremos o procedimento no elemento A[2], mas vamos compará-lo com A[3], A[4] e
A[5]. Comparando os elementos A[2] e A[3], verificamos que o valor de A[3] é menor que o de
A[2], por isso haverá troca.
A[1] = 2 | A[2] = 17 | A[3] = 45 | A[4] = 8 | A[5] = 5
Em seguida, o valor de A[2] deve ser comparado com o valor de A[4]. Como 8 é menor que
17, aremos uma permuta entre A[2] e A[4], deixando a matriz com a seguinte configuração:

A[1] = 2 | A[2] = 8 | A[3] = 45 | A[4] = 17 | A[5] = 5


Por fim, comparamos o valor do elemento A[2] com o valor de A[5], que também é menor que
o atual valor de A[2]; logo, haverá nova permuta, conorme indicado no esquema:
A[1] = 2 | A[2] = 5 | A[3] = 45 | A[4] = 17 | A[5] = 8
Agora, vamos comparar a próxima posição (A[3]) com os elementos restantes (A[4] e A[5]). O
valor 45 do elemento A[3] será comparado com o valor 17 do elemento A[4]. Como 17 é menor que
45, haverá permuta entre A[3] e A[4].
A[1] = 2 | A[2] = 5 | A[3] = 17 | A[4] = 45 | A[5] = 8
O valor 17 do elemento A[3] será comparado, desta vez, com o valor 8 do elemento A[5].
Como 8 é menor que 17, haverá permuta.
A[1] = 2 | A[2] = 5 | A[3] = 8 | A[4] = 45 | A[5] = 17
Não há mais elementos a serem comparados com A[3], portanto o valor 8 já está na posição final.
A[1] = 2 | A[2] = 5 | A[3] = 8 | A[4] = 45 | A[5] = 17
Para finalizar o algoritmo, alta apenas compara r o elemento A[4] com o A[5]. Como o valor
17 de A[5] é menor que o valor 45 de A[4], eles serão trocados: A[4] passa a ter o valor 17 e A[5],
o valor 45:
A[1] = 2 | A[2] = 5 | A[3] = 8 | A[4] = 17 | A[5] = 45

Não há mais comparações a serem eitas. Pode-se notar que a classificação oi realizada, ou
seja, a matriz está ordenada:
A[1] = 2 | A[2] = 5 | A[3] = 8 | A[4] = 17 | A[5] = 45
Para outros tipos de dados, como caractere ou string (cadeia), o processo de classificação segue
os mesmos passos; o algoritmo é o mesmo, só muda o tipo de dado. Lembre-se de que a ordem a
ser considerada é a da tabela ASCII. Logo, “A” tem valor menor (vem antes) que “B” e “A” também é
menor que “a”; essa ordem é dada pelo valor numérico associado a cada caractere.

76 Algoritmos - Técnicas de Programação


Exemplo
Desenvolver um programa que leia um conjunto de nomes de 20 estudantes inscritos na prova
do ENEM. Com esses nomes, realizar uma ordenação crescente para acilitar a localização do
nome na lista que será afixada no quadro de avisos da escola.
Solução
Deve-se utilizar uma matriz de uma dimensão (vetor) para armazenar os nomes dos estudan-
tes. Essa matriz pode ser preenchida por meio de um laço. A cada iteração o sistema receberá
um nome e alimentará o vetor. Para a ordenação, é preciso aplicar o algoritmo de troca estuda-
do, azendo as devidas comparações, de modo que, ao final, o conjunto esteja ordenado.

Diagrama de blocos Português estruturado


Início programa LISTA_NOME_ORDENADA

var
I 1,20,1
ESTUD : conjunto[1..20] de cadeia
I, J : inteiro
ESTUD[I]
X : cadeia
início

I 1, 19, 1
para I de 1 até 20 passo 1 faça
leia ESTUD[I]
J 1,20,1
 m_para

para I de 1 até 19 passo 1 faça


ESTUD[I] > S
ESTUD[J] para J de I + 1 até 20 passo 1 faça
N
X ESTUD [I] se (ESTUD[I] > ESTUD[J]) então
ESTUD [I] ESTUD [J]
ESTUD [J] X X ← ESTUD[I]

ESTUD[I] ← ESTUD[J]
ESTUD[J] ← X
 m_ se
 m_ pa ra
I 1,20,1
 m_ pa ra

ESTUD[I]
para I de 1 até 20 passo 1 faça
escreva ESTUD[I]
Fim
 m_ pa ra

Figura 6.1 - Diagrama de blocos para a


ordenação dos nomes dos estudantes. m

Aplicação Prática de Matrizes 77


abela 7.3 - Nova estrutura para o registro FICHA_ACADEMICA
FICHA_ACADEMICA
Nome docampo Tipo de dados
nome cadeia
série inteiro
turma caractere

disciplina cadeia
falta conjunto[1..4]de inteiro

nota conjunto[1..4]de real

tipo

FICHA_ACADEMICA = registro

NOME : cadeia

SERIE : inteiro

TURMA : caractere

DISCIPLINA : cadeia

FALTA : conjunto[1..4] de inteiro

NOTA : conjunto[1..4] de real

m_registro

var

aluno : cha_academica

Note que a definição para a criação da variável não soreu ajuste; houve alteração apenas na
estrutura do registro.

7.4 Tipo de dado derivado: novo tipo


No início deste capítulo, vimos que podemos criar e definir um novo tipo de dados com base
nos tipos primitivos. A acilidade de criar novos tipos dá a liberdade aos desenvolvedores de abstrair
inormações em estruturas mais simples de ser entendidas do ponto de vista do desenvolvimento.
Assim, imagine que queremos criar um tipo de dado denominado bimestre, que conterá dois vetores
de quatro posições, um para as altas para armazenar dados inteiros e outro para as notas, o qual é
capaz de receber dados reais. Então, podemos criar o tipo BIMESRE, conorme abela 7.4, e defini-
-lo dentro do registro FICHA_ACADEMICA (observe na abela 7.5) por meio da variável boletim.

90 Algoritmos - Técnicas de Programação


abela 7.4 - Definição do tipo BIMESRE
BIMESTRE
Nomedocampo Tipo de dados

falta conjunto[1..4]deinteiro

nota conjunto[1..4]dereal

abela 7.5 - Estrutura do registro FICHA_ACADEMICA com uso do tipo bimestre


FICHA_ACADEMICA
Nomedocampo Tipo de dados
nome cadeia
série inteiro
turma caractere
disciplina cadeia
boletim bimestre

O português estruturado para a estrutura criada na abela 7.5 pode ser observado a seguir:
tipo

BIMESTRE = registro

FALTA : conjunto[1..4] de inteiro

NOTA : conjunto[1..4] de real

m_registro

FICHA_ACADEMICA = registro

NOME : cadeia

SERIE : inteiro

TURMA : caractere

DISCIPLINA : cadeia
BOLETIM : bimestre

m_registro

var

ALUNO : cha_academica

emos na especificação do registro FICHA_ACADEMICA a criação do campo boletim cujo


tipo é BIMESRE. Já o tipo BIMESRE é ormado por dois vetores (matriz unidimensional) predefi-
nidos. Mais uma vez, observe que nada oi modificado na definição da variável aluno.

Programação com Registros 91


7.5 Matriz de registro
Com o que aprendemos até agora, conseguimos criar estruturas para armazenar grande quan-
tidade de dados heterogêneos, porém a estrutura de registro criada até então suporta armazenar
somente os dados de um aluno por vez, o que nos remete ao mesmo problema trabalhado no Capí-
tulo 5, quando vimos que, para armazenar mais de uma inormação do mesmo tipo, podemos criar
um vetor ou uma matriz com várias posições (índices), em que cada dado específico tem sido arma-
zenado em uma posição.
Aqui, em registros, podemos nos utilizar da mesma estrutura de vetores e matrizes, ou seja,
criar um vetor de registros com várias posições; em cada posição (indexada por um índice), temos
um conjunto de dados totalmente isolado.
Note que, uma vez criada a estrutura do registro, conorme visto anteriormente, basta criar-
mos uma variável que seja definida como um vetor do tipo do registro. Vejamos o seguinte exemplo:
Considere uma sala de aula com cinco alunos.
tipo
BIMESTRE = registro
FALTA : conjunto[1..4] de inteiro
NOTA : conjunto[1..4] de real
m_registro
FICHA_ACADEMICA = registro
NOME : cadeia
SERIE : inteiro
TURMA : caractere
DISCIPLINA : cadeia
BOLETIM : bimestre
m_registro
var

ALUNO : conjunto[1..5] de cha_academica

Após o uso do comando var, é indicada a variável de registro aluno, ormada por um conjunto
(vetor) de cinco registros do tipo de dado derivado FICHA_ACADEMICA.

92 Algoritmos - Técnicas de Programação


processamento muito baixo. Por exemplo, digamos que o nosso problema srcinal seja pesquisar pela
palavra “incondicional” em um glossário com 1000 verbetes. Se utilizarmos um algoritmo que divide
o problema em dois subproblemas, podemos ter duas instâncias de 500 verbetes cada.
Para ficar mais ácil de entender, imaginemos uma situação na qual precisemos computar a
soma de n números x0 a xn-1. Considerando que n > 0, podemos, então, dividir o problema em pelo
menos dois subproblemas:
» soma dos n/2 primeiros números do conjunto;
» soma dos n/2 últimos números do conjunto.
Na prática, houve um desmembramento dos dados de entrada. Dividimos o conjunto de dados
em dois. Logo, surgiram dois subproblemas menores, mas similares ao problema srcinal: computar
a soma. O próximo passo é, portanto, resolver os dois subproblemas. Uma vez resolvidos, a combi-
nação das soluções nos garante a solução do problema srcinal:
Sx(0,n-1) = (x0 + ... + x(n/2)-1) + (xn/2 + ... + xn-1)
Note que esse é um problema simples que poderíamos resolver de uma orma igualmente sim-
ples, pela orça bruta, sem uso de técnicas sofisticadas. Inclusive, não há ganho de eficiência se resol-
vermos esse algoritmo por meio de um único laço, considerando de uma só vez todo o conjunto de
dados. IssoEssa
conquista. mostra que nem
premissa todos os problemas
é verdadeira até mesmosão
paramelhorados por meio
outras técnicas da técnica deEis,
de programação. divisão
então,e
a responsabilidade do programador em escolher a técnica mais adequada para o seu problema.
Então, quando devo aplicar a técnica de divisão e conquista? Basicamente quando:
» o seu problema puder ser particionado em problemas similares menores, o que chama-
mos de resolução por indução;
» os subproblemas gerados possam ser solucionados independentemente uns dos outros;
» or possível combinar as soluções dos subproblemas de modo eficiente.
Vejamos agora outro exemplo, um pouco mais complexo. Digamos que desejamos eetuar uma
busca em um vetor ordenado.
O modo mais trivial de solucionar esse problema é por meio da pesquisa sequencial, estudada no
Capítulo 6. odavia, em um conjunto de dados muito grande, a pesquisa sequencial é pouco eficiente.
Nesse caso, a divisão e conquista passam a ser uma estratégia interessante se o conjunto de dados esti-
ver ordenado. Um dos algoritmos de busca por divisão e conquista mais utilizados é a pesquisa binária.
A pesquisa binária consiste em dividir o conjunto de dados (com n elementos) em duas partes,
por isso o adjetivo “binário”. Logo, o problema também éreduzido a dois subproblemas menores. Se
o conjunto tiver apenas um valor (n = 1) e o elemento procurado or a1, então o valor procurado oi
encontrado; caso contrário, esse valor não está no conjunto.
Se n > 1, então verificaremos se a chave de busca está na posição do meio (n/2), ou seja, se
k = an/2. Se estiver, o valor procurado oi encontrado; caso contrário, será necessário continuar a
busca. Como o conjunto está ordenado, é simples saber se o valor procurado, caso exista, está na pri-
meira ou na segunda parte do conjunto.

Utilização de Sub-rotinas 99
Dividimos, portanto, o problema em dois a depender do valor da chave de busca:
» busca binária nos elementos a1 até a(n/2)-1 do vetor;
» busca binária nos elementos a (n/2)+1 até an do vetor.
O processo de divisão e conquista se repete até que, então, o valor procurado seja encontrado
ou descubra-se que o valor não está no vetor. Note que o processo de divisão é realizado quantas
vezes or necessário.
Perceba também que nesse algoritmo, os processos de dividir e de conquistar são iterativos e
incrementais, ou seja, ocorrem várias vezes, e a cada vez que ocorrem, o algoritmo está mais pró-
ximo de encontrar a chave de busca 1 (ou de inormar que ela não consta no conjunto de dados).
Note que esse método é semelhante ao que realizamos ao procurar uma palavra (nossa chave
de busca) em um dicionário.
Vejamos um exemplo da aplicação desse algoritmo. Encontrar o número 4 no vetor ordenado
V = {1, 3, 4, 9, 10, 11, 15}. Antes de resolver, saiba que o vetor V possui 7 elementos, logo n = 7.
A primeira decisão é aplicada: 4 está na posição n/2, ou seja, na posição 3? Não, pois nessa
posição está o valor 9. Então, dividiremos o vetor em dois subconjuntos:
»

valores abaixo da posição 3: V1 = {1, 3, 4};


» valores acima da posição 3: V2 = {10, 11, 15}.
Como 4 é menor que 9, então o conjunto representado pelo vetor V2 será descartado e, mais
uma vez, o algoritmo de busca binária será executado, dessa vez sobre o vetor V1.
Neste subproblema, a primeira decisão será similar à utilizada no problema srcinal: 4 é menor
que o elemento do meio? A reposta é não. O elemento do meio (posição 1) é 3. Então, o vetor será
novamente dividido em dois novos subconjuntos:
» valor abaixo da posição 1: V11 = {1};
» valor acima da posição 1: V12 = {4}.

Como 4 é maior que 3, o conjunto de valores 1 3 4 9 10 1 1 15


abaixo de 3 (vetor V11) será descartado. Sobre o
vetor V12 será aplicado novamente o algoritmo de 1 3 4 9 10 11 15
busca binária. Verifique que o V12 possui apenas um
elemento. Logo, se o valor procurado or dierente do
1 3 4
valor desse elemento, o algoritmo deve inormar que
o valor procurado não se encontra no conjunto de
4
dados. Nesse caso, o valor procurado (4) é igual ao
elemento único de V12, logo, o valor procurado oi Figura 8.2 - Visualização da execução
encontrado, conorme se observa na Figura 8.2. do algoritmo de busca binária.

1 Chave de busca é o valor procurado no conjunto de dados.

100 Algoritmos - Técnicas de Programação


Veja, a seguir, o algoritmo em português estruturado e em diagrama de blocos.

Diagrama de blocos Português estruturado

programa BUSCA_BINARIA
INÍCIO
var

V : conjunto[
1..20] de inteiro
I 1,20,1
X, N, MEIO, ESQUERDA, DIREITA, I: inteiro

início

para I de 1 até 20 passo 1 faça


V [I]
leia V [I]

fm_para
N 20
ESQUERDA 0
DIREITA N N ← 20

ESQUERDA ← 0

DIREITA ← N
X

leia X

ESQUERDA <= DIREITA N enquanto (ESQUERDA <= DIREITA) faça

MEIO ← (ESQUERDA + DIREITA) DIV 2

S
MEIO (ESQUERDA + DIREITA) DIV 2 se (V[MEIO] = X) então

escreva MEIO

senão
N S
V [MEIO] = X se (V[MEIO] < X) então

ESQUERDA ← MEIO + 1
N S MEIO
V [MEIO] < X senão

DIREITA ← MEIO - 1
DIREITA MEIO - 1 ESQUERDA MEIO + 1
fm_se

fm_se
fm_enquanto

fm

FIM

Figura 8.3 - Diagrama de blocos


para o algoritmo de busca binária.

Utilização de Sub-rotinas 101


8.2 Programação top-down e bottom-up
Ao projetar um sofware, o programador e o projetista podem optar por desenvolvê-lo das
estruturas mais gerais para as mais específicas ( top-down) ou vice-versa (bottom-up).
Se optar pelo método top-down, primeiro será desenvolvida a estrutura geral do sofware e
definidos os componentes menores, mas estes serão desenvolvidos conorme o processo de desen-
volvimento avançar.
No método bottom-up, os módulos/componentes menores são desenvolvidos e testados, só
então são agregados para ormar o sofware projetado.
Numa programação top-down o sofware é desenvolvido a partir de refinamentos sucessivos,
ou seja, o projeto e a implementação do sofware evolui incrementalmente ao longo do processo de
desenvolvimento. Essa abordagem também é conhecida como método incremental. Um das van-
tagens do método top-down é eetuar todas as etapas do processo de desenvolvimento em partes
pequenas do sofware, logo, ações que só ocorreriam no final do processo são “adiantadas” e execu-
tadas várias vezes em pequenas porções do produto, como os testes unitários e testes com usuários.
Para ser eetivo, é preciso que as etapas de refinamento sejam simples e bem definidas e, além
disso, ao longo do desenvolvimento a estrutura basilar do projeto de sofware deve ser definida, o
que acilita, inclusive, os testes.
Por sua vez, a programação bottom-up também desenvolve o sofware em etapas. odavia,
nessa abordagem, uma proposta inicial do sofware é definida no início do processo de desenvolvi-
mento. Essa proposta contém inormações sobre todos os módulos/componentes que serão desen-
volvidos. Em seguida, são desenvolvidos os módulos/componentes detalhados.

8.3 Procedimentos
O programador deve sempre se lembrar de manter a legibilidade dos algoritmos e códigos-
-onte dos seus programas. Para isso, é preciso utilizar-se de vários mecanismos. Um deles é a modu-
larização do programa. Ao criar módulos de programas, o programador permite estabelecer ações
pontuais para cada porção de código, deixando o programa mais limpo e, consequentemente, mais
ácil de eetuar manutenção.
Atualmente, há diversas ormas de modularização. Neste capítulo, estudaremos duas ormas:
procedimentos e unções.
Procedimentos são subprogramas (também conhecidas por sub-rotinas), ou seja, partes de um
programa maior, com finalidade específica. Os procedimentos executam uma determinada tarea com
uso ou não de parâmetros de entrada, mas jamais retornam valores ao programa que o chamou. Os
parâmetros são valores enviados pelo programa principal para correta execução dos procedimentos.
odo procedimento deve ter uma assinatura. A assinatura é composta pelo identificador do
procedimento e seus parâmetros de entrada, caso tenha. ambém pode ter espaço para declaração de
variáveis. Essas variáveis só poderão ser utilizadas dentro do procedimento onde oram declaradas.

102 Algoritmos - Técnicas de Programação


Em português estruturado, podemos definir um procedimento desta orma:
Procedimento<nome do procedimento>(<lista de parâmetros>)
<comandos>

m_procedimento

Vejamos um exemplo de uso de procedimento:


procedimento Ordenacao_Vetor (VET: conjunto[1..N] de inteiro
, N: inteiro)
var

I, J : inteiro
X : cadeia
início

para I de 1 até 19 passo 1 faça


para J de I + 1 até 20 passo 1 faça
se (VET [I] > VET [J]) então
X ← VET [I]
VET [I] ← VET [J]
VET [J] ← X
m_se
m_para
m_para
m_procedimento

Para que um procedimento seja executado, é necessário que o computador processe um


comando de chamada. Esse comando, em geral, é ormado pelo identificador do procedimento
seguido dos parâmetros necessários, como no exemplo abaixo, em que o procedimento Ordenacao_
Vetor é chamado:
programa LISTA_NOME_ORDENADA

var

ESTUD : conjunto[
1..20] de cadeia
I: inteiro

início
para I de 1 até 20 passo 1 faça
leia ESTUD [I]
m_para

Ordenacao_Vetor(ESTUD, 20)

para I de 1 até 20 passo 1 faça


escreva ESTUD [I]
m_para
m

Utilização de Sub-rotinas 103


O último valor reere-se à variável N, que, por ter sido passada por valor à unção Cálculo, não
oi alterado dentro dessa unção. O valor inicial de N é 10 e se mantém o mesmo até o final da execu-
ção desse programa.
Veja que a principal dierença entre as duas ormas de passagem de parâmetros é que na passa-
gem por valor o conteúdo da variável é “copiado” para o parâmetro da sub-rotina. Na passagem por
reerência, o endereço de memória é atribuído ao parâmetro do subprograma. Com esse endereço, o
subprograma pode azer as alterações que desejar, e todas elas serão vistas em qualquer parte do pro-
grama, como neste exemplo:
Em português estruturado, podemos definir uma unção da seguinte orma:

função <nome da função>(<lista de parâmetros>) : tipo_retorno

Vejamos um exemplo de uso de unção:

função Media_Anual(VET : conjunto[1..N] de inteiro


, N : inteiro) : real
var

I, ACUMULADOR : inteiro
início

para I de 1 até N passo 1 faça


ACUMULADOR ← ACUMULADOR + VET[I]
m_para
Media_Anual← ACUMULADOR / 12
m_função

Nesse exemplo, considerando que oi lido o valor N = 10, será apresentada na tela a
seguinte saída:
10
100
100
O último valor reere-se à variável N, que, por ter sido passada por reerência à unção
Cálculo, oi alterado dentro dessa unção, dierente do que ocorreu no exemplo em que N oi pas-
sada por valor. Veja, também, que para passar valor por reerência a uma unção ou procedimento é
necessário colocar a palavra “var” antes do nome do parâmetro na assinatura da sub-rotina.

Vamos recapitular?

Neste capítulo, estudamos as características undamentais das sub-rotinas ou subprogramas, os


seus tipos (procedimentos e unções) e as características mais importantes, como passagem de parâme-
tros por valor e por reerência, escopo de variáveis e métodos top-down/bottom-up.

Utilização de Sub-rotinas 107


gora é com você

1) Escreva uma sub-rotina que receba por parâmetro um número inteiro e imprima se
ele é divisível por 7 ou não. Decida se usará procedimento ou unção e explique o
porquê da escolha.

2) Escreva um procedimento
determinado quee,receba
animal pertence por parâmetro
em seguida, imprima o nome
códigododogrupo
grupoe ao qual um
a constante
K para cálculo da taxa metabólica basal (MB), conorme tabela a seguir:

Códigodogrupo Nomedogrupo Constante(K)


1 Passeriformes 129
2 Não
passeriformes 78
3 MamíferosPlacentários 70
4 Marsupiais
Edentatas
e 49
5 Répteis 10

3) Escreva uma unção que receba por parâmetro o peso metabólico (PM) de um ani-
mal (peso total do animal expresso em quilogramas) e o grupo ao qual esse animal
pertence e calcule a taxa metabólica basal (MB). A taxa metabólica basal é o peso
metabólico elevado a 0,75 e multiplicado por uma constante K. O valor de K depen-
de do grupo do animal, conorme tabela do exercício anterior.
Fórmula de cálculo da taxa metabólica basal: MB = (PM ↑ 0,75) * K
4) Escreva um procedimento que receba por parâmetro o peso metabólico (PM) de um
animal (peso total do animal expresso em quilogramas), o grupo ao qual esse animal
pertence e uma letra (flag). Se a letra or B, o procedimento deve chamar uma unção
para calcular a taxa metabólica basal (MB). Se a letra or E, o procedimento deve
chamar
da ME,umausarunção para acalcular
a órmula seguir. aOtaxa metabólica
valor específica
da constante (ME). Para
K corresponde o cálculo
ao grupo do
animal, sendo o mesmo tanto para o cálculo da MB como da ME.
Fórmula de cálculo da taxa metabólica específica: ME = (PM ↑ 0,25) * K

108 Algoritmos - Técnicas de Programação


Medidas de
Complexidade
de Algoritmos
9
Para começar

Neste capítulo, serão abordados de maneira introdutória e mais didática possível conceitos preli-
minares do uso de medidas de complexidade de algoritmos para estudantes iniciantes em programação
de computadores.

9.1 Análise de algoritmos

O que
um livro apresentamos
introdutório sobreaqui sobre
lógica análise de algoritmos
de programação e suas complexidades
de computadores não é comum
para programadores em
iniciantes,
como este. A disponibilidade de livros em português é pequena e o oco desse estudo é ministrado
em cursos mais avançados de programação. Assim sendo, o tema ora abordado constitui-se em uma
visão preliminar com o objetivo de indicar ao nosso estudante os próximos passos a serem seguidos
no estudo da lógica de programação e no aproundamento desse estudo, que se estende com a apren-
dizagem de uma disciplina denominada Estrutura de Dados.
A expressão Análise de Algoritmos, como é usada e como a conhecemos, oi idealizada por
Donald E. Knuth quando publicou em 1968 o primeiro volume de uma série de sete livros intitulado
Te Art o Computer Programming (A Arte da Programação de Computadores) não tendo este traba-
lho tradução para o português.

109
A disciplina de Análise de Algoritmos tem por objetivo estudar os problemas computacionais
que se apresentam de orma recorrente, que se mostram de dierentes ormas (FEOFILOFF, 2013).
Nesse sentido, podemos entender que essa disciplina visa, para um dado problema, nos mostrar:
» a prova de que o algoritmo que estamos usando está correto.
» a estimativa da complexidade do tempo que a execução do algoritmo consome.
» a estimativa do espaço de memória usada para seu armazenamento.

Veja que, com base no exposto fica ácil concordar com as palavras de Almeida (2000, p. 3)
que nos diz que um “algoritmo não é a solução de um problema, pois, se assim osse, cada problema
teria um único algoritmo”. Note que poderão existir para a solução de um problema vários cami-
nhos, vários algoritmos. Assim sendo, um problema poderá ser resolvidos com o uso de vários algo-
ritmos (PRESES, 2011), Almeida (2000, p. 3) acrescenta ainda que “algoritmo é um caminho para
a solução de um problema, e em geral, os caminhos que levam a uma solução são muitas”. Análise de
Algoritmos é a orma com a qual poderemos medir qual algoritmo é o melhor para responder a certo
problema, pois como afirma Prestes (2011) “o ato de um algoritmo resolver um dado problema não
significa que seja aceitável na prática”.
Se tivermos dois algoritmos para a solução de um mesmo problema, a ação prática da Análise
de Algoritmos nos permitirá decidir dos dois algoritmos ornecidos, aquele que seja melhor eficiente
(otimilidade de algoritmos).
realiza sua tarea É undamental
até atingir seu sabermos
objetivo e que eficáciaque
é o eficiência é asi.orma
objetivo em como um devem
Os algoritmos algoritmo
ser
eficazes, devem atender seus objetivos, devem ornecer uma solução de boa qualidade a certo pro-
blema. Assim, a eficiência é o grau de satisação de boa qualidade medido pela Análise de Algoritmos
para saber qual dos algoritmos encontrados é o melhor para solucionar o problema existente.
Para analisar a eficiência no uso de certo algoritmo, é necessário levar em consideração a exis-
tência de duas possibilidades de análise, como mostra Matos (2008, p. 13):
» Pormenorizada: mais exata e direta, em geral menos útil, pois:
é expressa em segundos;
resultado da avaliação da eficiência (por exemplo, tempo gasto): único e dependente da
velocidade e características do processador.
» Por meio de ordens de grandeza: ignora as constantes multiplicativas e é uma análise
assintótica (método para medir o tempo total gasto por um algoritmo para realizar certa
tarea computacional), isto é:
expressa em ordens de grandeza;
resultado da avaliação da eficiência: paramétrico (uma unção do comprimento dos
dados) e independente da velocidade e características do processador.
Com base nessa explicação, podemos dizer que a Análise de Algoritmos é uma disciplina de
Engenharia, de Matemática ou da Ciência da Computação, dependendo do enoque que queira se
dar, que procura prever o comportamento de um algoritmo antes mesmo que seja implementado

110 Algoritmos - Técnicas de Programação


e eetivamente colocado “em produção” (FEOFILOFF, 2013, p. 9). Este tipo de análise possibilita
ganho econômico na produção de sofware.

Amplie seus conhecimentos


O estudo de análise e complexidade de algoritmos pode ser ampliado com base na consulta de diversos outros materiais
publicados na grande rede mundial (Internet), em português, a partir dos seguintes sítios (acesso em: 19 dez. 2013):
http://www.inf.ufrgs.br/~prestes/site/Welcome.html (slides);
http://www.youtube.com/watch?v=j7BKN7phIeY (vídeo aula);
http://www.ime.usp.br/~pf/analise_de_algoritmos/ (diversos materiais);
http://www.ime.usp.br/~pf/livrinho-AA/AA-BOOKLET.pdf (minicurso de análise de algoritmos);
http://www.decom.ufop.br/toffolo/ (diversos materiais de apoio);
http://www.dcc.fc.up.pt/~ap/taa/1011/ (apostila com notas de aula).

9.2 Modelo de tempo e espaço: otimilidade


de algoritmos

Nós, programadores de computador, temos que sempre levar em consideração que todo pro-
jeto de programa pode vir a ser influenciado pelo estudo de seus comportamentos. Após um pro-
blema ser analisado e as decisões sobre o projeto serem tomadas, o algoritmo em si deve ser imple-
mentado na orma de um programa de computador. Nesse instante, devemos analisar as inúmeras
alternativas que poderemos aplicar, devemos considerar os aspectos de tempo de execução e espaço
de memória ocupado. As alternativas encontradas para o desenvolvimento desses algoritmos podem
ser localizadas em outras disciplinas tais como: pesquisa operacional, otimização, teoria de graos,
estatísticas, probabilidades etc. (CLAUDINO, 2013).
Knuth (apud CLAUDINO, 2013, p. 8) inorma que “na área de estudo dos algoritmos, há dois
tipos de problemas bem distintos” a serem considerados: a análise de um algoritmo particulare a
análise de uma classe de algoritmose assim os especifica:
»
A análise de um algoritmo particularleva em conta o custo do uso de um dado algoritmo
para equacionar um problema específico. Características importantes do algoritmo devem
ser investigadas, geralmente uma análise do número de vezes que cada parte do algoritmo
deve ser executada, seguida do estudo da quantidade de memória necessária a ser utili-
zada por certo computador.
» A análise de uma classe de algoritmosvisa identificar o algoritmo de menor custo possível
para resolver um determinado problema particular. oda uma amília algoritmos para resol-
ver um problema específico deve ser investigada com o objetivo de identificar o algoritmo
que seja o melhor possível. Isso significa colocar limites para a complexidade computacio-
nal dos algoritmos pertencentes à classe. Por exemplo, é possível estimar o número mínimo
de comparações necessáriaspara ordenar “n” números por meio de comparações sucessivas.

Medidas de Complexidade de Algoritmos 111


Quando determinamos o menor custo possível e usamos para resolver problemas de determi-
nada ordem, como no caso das ordenações de valores ou dos padrões usados para estabelecer o pro-
cessamento de uma pesquisa de dados em vetores, temos nestes a medida da dificuldade inerente para
resolvê-los. Além disso, quando o custo de um algoritmo é igual ao menor custo possível, então po-
demos concluir que o algoritmo é ótimo para a medida de custo considerada (LOUREIRO, 2005;
OFFOLO, 2012). É com base nessas considerações que nós podemos medir o nível de otimilidade de
um algoritmo.

Em relação à otimilidade de algoritmos Potros (2013, p. 3) nos orienta que “para um deter-
minado problema, pode existir várias resoluções algorítmicas, então se az necessário escolher o
melhor” e acrescenta que “se a mesma medida de custo é aplicada a dierentes algoritmos, então é
possível compará-los e escolher o mais adequado para resolver o problema”.
Entre as várias maneiras a qual se pode medir o custo de utilização de um algoritmo Ziviani
(1999, p. 4) nos mostra que a ”orma mais adequada de se medir o custo de utilização de um algoritmo
é através do uso de um modelo matemático”, acrescenta que “o conjunto de operações a serem execu-
tadas deve ser especificado, assim como o custo associado com a execução de cada operação”. Desta
orma, o modelo matemático indicado para medir o custo de execução de certo algoritmo reere-se ao
uso de uma unção de complexidade denominada (n).
A unção de complexidade (n) pode ser utilizada para a obtenção da métrica de tempo
(medida do tempo de execução consumida, dado um conjunto de entrada de dados, que certo
algoritmo requer para produzir uma resposta) ou da métrica de espaço (medida da quantidade de
memória de computador que o algoritmo necessita para sua execução).
Se a unção de complexidade (n) or usada para medir a quantidade do tempo necessário
para executar certo algoritmo de tamanho n, então  é considerada como unção de complexidade
de tempo do algoritmo. Caso a unção de complexidade (n) seja usada para medir a quantidade da
memória de computador necessária para executar um algoritmo de tamanho n, então  é chamada
unção de complexidade de espaço do algoritmo (ZIVIANI, 1999, p. 4). Podemos considerar como
relações uncionais os aspetos:
» emporal: unção de complexidade de tempo que tem por finalidade relacionar o tama-
nho da entrada com o tempo de execução:
t = (n)
» Espacial: unção de complexidade de espaço que tem por finalidade relacionar o tamanho
da entrada com o espaço de memória necessário para o armazenamento requerido:
e = (n)
Em termos práticos o ator de medida mais usado é a unção de complexidade de tempo: t = (n).
Isso significa que essa unção é normalmente calculada em primeira instância, ficando, a unção de com-
plexidade de espaço:e = (n) em segunda instância. A escolha da unção de complexidade a ser usada
dependerá do tipo de métrica que se deseja avaliar para escolher o algoritmo de melhor otimilidade.

112 Algoritmos - Técnicas de Programação


As instruções N ← tamanho(FRASE) e M ← tamanho(JANELA) azem uso da unção tama-
nho() definida na Figura 9.2. Ao ser verificada a execução do programa por meio de um teste
de mesa obter-se-á como resultado da ação da execução da instrução escreva I a apresentação
dos valores 4 e 9 reerentes às posições iniciais onde a janela AB ocorre na sentença FRASE.

9.4 Fundamentos de retrocesso


Um algoritmo de retrocesso ( backtraking) é um mecanismo de ação em proundidade que visa
verificar de maneira exaustiva todas as possibilidades de solução de certo problema.
Um mecanismo de backtraking bem popular e comum é o uso de unções recursivas. Uma un-
ção recursiva é uma unção que az chamadas a si mesma. O uso de recursividade proporciona a
escrita de um código mais elegante com alto grau de abstração.

Exemplo
Como exemplo de recursividade considere uma unção que calcule o valor do atorial de um

número inteiro qualquer N.


Diagrama de blocos
Início FATORIAL (N)

N S
LIMITE N <= 1

FATORIAL FATORIAL (N - 1) X N FATORIAL 1


FATORIAL
(LIMITE)

Fim RETORNA FATORIAL

Figura 9.4 - Diagramas de blocos com unção FAORIAL recursiva.

Medidas de Complexidade de Algoritmos 121


Português estruturado

programa CALC_FAT

função FATORIAL(N : inteiro


) : inteiro
início

se (N <= 1) então
FATORIAL ← 1
senão

FATORIAL ← FATORIAL(N - 1) * N
m_se
m

var

LIMITE : inteiro

início

escreva "Qual fatorial: " leia LIMITE


escreva FATORIAL(LIMITE)

m

Ao observar a unção recursiva FAORIAL() do algoritmo de programa CALC_FA, nota-


-se dentro do bloco adjacente para condição N <= 1 (alsa) a operação de cálculo matemático
FAORIAL ← atorial(N − 1) * N, em que FAORIAL é atribuído pelo resultado da operação
FAORIAL(N − 1) * N. O parâmetro N determina o número de vezes que a operação deve ser
eetuada e atorial(N − 1) é uma nova instância de chamada da unção a si mesma com o valor
do parâmetro N menos 1.
Imagine a unção recursiva FAORIAL() receber como passagem de parâmetro por valor o 5.
Neste caso, o resultado dessa operação será 120. Para chegar a esse resultado, são necessários
os seguintes passos:
1) Ao passar o conteúdo 5 para a unção recursiva FAORIAL() e pelo ato de esse valor
não ser menor ou igual a 1, será eetuada a operação FAORIAL ← FAORIAL(N − 1) *
N. Neste caso, FAORIAL ← FAORIAL(4) * 5, sendo o valor 5 armazenado na pilha de
memória.
2) Em seguida, o conteúdo 4 obtido a partir de 5 − 1, não sendo um valor menor ou igual
a 1, é passado à unção recursiva FAORIAL() que eetua a operação FAORIAL ←
FAORIAL(N − 1) * N. Neste caso, FAORIAL ← FAORIAL(3) * 4, sendo o valor 4
armazenado na pilha de memória.

122 Algoritmos - Técnicas de Programação


3) O conteúdo 3 obtido a partir de 4 − 1, não sendo um valor menor ou igual a 1, é passado
à unção recursiva FAORIAL()que eetua a operação FAORIAL← FAORIAL(N − 1)
* N. Neste caso, FAORIAL ← FAORIAL(2) * 3, sendo o valor 3 armazenado na pilha
de memória.
4) Depois, o conteúdo 2 obtido a partir de 3 − 1, não sendo um valor menor ou igual a
1, é passado à unção recursiva FAORIAL() que eetua a operação FAORIAL ←
FAORIAL(N − 1) * N. Neste caso, FAORIAL ← FAORIAL(1) * 2, sendo o valor 2
armazenado na pilha de memória.
5) Por último, o conteúdo1 obtido a partir de 2 − 1 é menor ou igual a 1 e, por esta razão,
é atribuído à variável FAORIAL o valor 1. Neste caso, a unção recursiva FAORIAL()
retorna o valor 1 e multiplica-o pelo valor 2 armazenado na pilha, obtendo o resultado 2
que é então retornado pela própria unção recursiva FAORIAL(). Neste caso o valor 1 é
destruído na memória, permanecendo em memória apenas o valor 2.
6) Na sequência, o valor 2 retornado é multiplicado pelo valor empilhado 3, obtendo o
valor 6 que é então retornado pela unção recursiva FAORIAL() e o valor 2 é destruído
da memória, permanecendo em memória apenas o valor 6.
7) Após o retorno, o valor6 é multiplicado pelo valor empilhado 4, obtendo o valor 24 que
é então retornado pela unção recursiva FAORIAL() e o valor 6 é destruído da memó-
ria, permanecendo em memória apenas o valor 24.
8) Por último, o valor24 é multiplicado pelo valor empilhado 5, obtendo o valor 120 que é
então retornado pela unção recursiva FAORIAL() e o valor 24 é destruído da memó-
ria, permanecendo em memória apenas o valor 120.

Após a obtenção do valor120, chega-se à quin- FATORIAL (5)


ta e última etapa do empilhamento dos valores FATORIAL (5 - 1) * 5

calculados, em virtude da passagem de parâ- FATORIAL (4 - 1) * 4


FATORIAL (3 - 1) * 3
metro de valor do conteúdo 5 para a unção FATORIAL (2 - 1) * 2
FAORIAL(5). Neste caso, ocorre o encerra- FATORIAL (1 - 1) * 1

mento
o trechodado
unção e o retorno
programa do valor120
que eetuou para
a chamada
FATORIAL 1
da unção. A Figura 9.5 demonstra grafica-
mente a lógica de uncionalidade e de ação e
mostra como unciona uma unção recursiva RETORNA 1
(backtraking). Cada instância de chamada da RETORNA 2 * 1
unção recursivaFAORIAL()ocorre de orma RETORNA 3 * 2
RETORNA 4 * 6
a empilhar cada uma das instâncias da unção
RETORNA 5 * 24
em operação para depois, no retorno, eetuar a RETORNA 120
multiplicação sucessiva típica do valor retorna-
do com o valor armazenado na pilha, a fim de Figura 9.5 - Esquema lógico de
uncionalidade e ação de unção recursiva.
calcular a atorial solicitada.
(MANZANO; FIGUEIREDO, 2012)

Medidas de Complexidade de Algoritmos 123


SALIBA, W. L. C.écnica de Programação: Uma Abordagem Estruturada. São Paulo: Makron, 1993.
SCIENCE MUSEUM. Te Babbage Engine. Computer History Museum. Disponível em: <http://
www.computerhistory.org/babbage/adalovelace/>. Acesso em: 12 nov. 2013.
SEBESA, R. W. Conceitos de Linguagens de Programação
. 5. ed. Rio Grande do Sul: Bookman, 2003.
SIMCSIK, . OMIS: Organização, Métodos, Inormação, Sistemas. São Paulo: Makron, 1992.

SZWARCFIER, J. L.; MARKENZON,


Rio de Janeiro: Editora LC, 1994. L.Estruturas de Dados e seus Algoritmos. Editora LC,

OFFOLO, . Análise de Algoritmos . Minas Gerais: universidade Federal de Ouro Preto, 2012.
Disponível em: <http://www.decom.uop.br/toffolo/ensino/todas/bcc202_2012-1/aulas/>. Acesso
em: 19 dez. 2013.
VENANCIO, C. F.Desenvolvimento de Algoritmos:Uma Nova Abordagem. São Paulo: Érica, 1998.
VERZELLO, R. J. Processamento de Dados. São Paulo: McGraw-Hill, 1984.
WEBER, R. F. Fundamentos de Arquitetura de C omputadores. 3. ed. Porto Alegre: Instituto de
Inormática UFRGS: Editora Sagra Luzzato, 2004.

WIRH, N. Algoritmos e Estruturas de Dados. São Paulo: Prentice-Hall, 1989.


ZIVIANI, N. Projeto de Algoritmos com Implementação em Pascal e C . 4. ed. São Paulo: Pio-
neira, 1999.

Bibliografia 127
Marcas Registradas

odos os nomes registrados, marcas registradas ou direitos de uso citados neste livro pertencem aos
seus respectivos proprietários.

128 Algoritmos - Técnicas de Programação

Вам также может понравиться