Introdução aos Algoritmos - Giga Mundo

Propaganda
3 Introdução aos algoritmos
3.1 Motivação
3.1.1 Por que estudar algoritmos?
Olhe em sua volta, ou melhor, olhe em seu computador: você já percebeu
quantos softwares diferentes você utiliza diariamente? O próprio sistema operacional,
carregado inicialmente, antes mesmo que você possa executar algo, é composto por uma
série de processos (e podemos entender cada processo como sendo um programa que
atua de forma independente dos demais).
Se você já precisou em algum momento elaborar um artigo científico, um
panfleto publicitário ou um trabalho escolar, provavelmente já se utilizou de algum
processador de texto. Se já necessitou de alguma ferramenta para realização de cálculos,
talvez tenha usado uma planilha eletrônica ou mesmo uma calculadora. Todos esses
programas em nosso computador, todos esses softwares, foram criados por alguém. E o
que aconteceria se você mesmo pudesse criar softwares que desejasse?
Talvez você já tenha pensado alguma vez em algum programa que funcionasse
como uma calculadora, mas com uma finalidade bastante específica, e não encontrou
uma versão já pronta. E se você tivesse o conhecimento necessário para implementá-la
ou ao menos soubesse um meio de especificar seu funcionamento nos menores detalhes
para um programador tal que ele pudesse criá-la para você? Não seria fantástico?
Pois bem, é para isso que estamos aqui, para aprender algoritmos, que são uma
forma de descrever como uma determinada tarefa pode ser executada – e ao descrever
corretamente como a tarefa pode ser executada, conseguimos também descrever como
deve funcionar um software para executar aquela tarefa.
3.1.2 O que é um programa / software?
É bem provável que você já tenha utilizado algum software em algum momento
de sua vida: há processadores de textos, ferramentas para criação de apresentações,
calculadoras, planilhas eletrônicas, ferramentas para edição gráfica, softwares para
gestão de estoque ou folha de pagamentos, simuladores, jogos eletrônicos, etc. Todos
eles são exemplos de software.
Dizemos sempre que um computador pronto para uso é formado por “hardware
mais software”. Hardware é todo equipamento físico necessário para que o mesmo
funcione. Já o software é a parte lógica, necessária para determinar como o hardware
deve se comportar, que informações devem ser requisitadas e enviadas ao usuário.
Enfim, um software (ou programa, como também chamamos) é todo sistema
para computador que executa tarefas de forma sequencial. E podemos compreender uma
tarefa como sendo um conjunto de comandos e decisões necessários para alcançar um
determinado objetivo.
Agora que já sabemos que um software é um sistema capaz de executar uma
tarefa de forma sequencial, surge uma dúvida: como podemos, então, descrever como o
software deveria resolver um problema?
Esse é o papel do algoritmo.
3.2 Definição de algoritmo
O conceito de algoritmo não existe somente no mundo da Computação, sendo
empregado em toda tarefa que seja complexa e aparente necessitar de uma forma para
especificar como deve ser executada. Um algoritmo é, assim, uma sequência de ações
finitas que descreve como um problema deve ser resolvido.
Exemplos de algoritmos são: o processo de troca de um pneu, modo como os
cabelos devem ser penteados (sim, é possível descrever um algoritmo para isso!) e o
cálculo da média de um aluno (neste caso, podemos pode-se pensar até em um
programa que poderia ser implementado a partir desse algoritmo – e seria muito útil!).
3.3 Características de um algoritmo
Uma vez que um algoritmo descreve como uma determinada tarefa pode ser
executada, algumas características devem estar presentes tal que o mesmo possa ser
realmente aplicável na prática, seja por um humano, seja por uma máquina:
•
Finitude – Todo algoritmo deve ser formado por um conjunto finito de
passos, isto é, possuir início e fim. Um algoritmo não pode, então, ser
executado indefinidamente;
•
Definição – Cada ação ou passo de um algoritmo deve ser escrito de
forma bastante precisa, sem ambigüidades ou dúvidas quanto à sua
execução;
•
Sequencial – Um algoritmo é formado por uma série de passos que
devem ser executados em uma ordem seqüencial;
•
Entradas – Um algoritmo deve apresentar zero ou mais entradas, isto é,
informações que devem ser inseridas por um usuário ou por outra fonte
externa;
•
Saídas – Um algoritmo deve apresentar uma ou mais saídas, isto é,
informações pré-definidas e/ou resultantes do processamento das
entradas;
•
Eficiência – Um algoritmo deve ser eficiente, significando que suas
operações devem ser suficientemente básicas tal que um ser humano seja
hábil a executá-las com precisão em papel e lápis em um tempo finito.
3.4 Formas de representação dos algoritmos
Há várias formas de representar um algoritmo, cada qual com suas próprias
vantagens e desvantagens, sendo as mais comuns a descrição narrativa, representação
gráfica, o uso de pseudocódigo e implementação em uma linguagem de programação.
Analisaremos agora cada uma dessas formas.
3.4.1 Descrição narrativa
A descrição narrativa é a forma mais comum de encontrarmos algoritmos. Toda
vez que tentamos descrever como uma tarefa deve ser executada por meio de um texto,
seja ele verbal ou escrito, estamos nos usando de uma descrição para representar o
algoritmo capaz de resolver aquele problema.
Um exemplo bastante comum de descrição narrativa é a receita de um bolo.
Veja só como um cozinheiro pode auxiliar outro lhe oferecendo uma descrição da
receita:
Separar os ingredientes
Bater os ovos em ponto de neve na batedeira
Acrescentar açúcar e farinha de trigo
Acrescentar uma colher de manteiga
Acrescentar uma colher de fermento em pó
Colocar na forma
Colocar no forno e assar
Tirar da forma e servir
Fim do processo!
A principal vantagem dessa forma de representação é que ela é muito fácil de
ser compreendida e empregada no dia-a-dia, qualquer um capaz de compreender alguma
língua pode falar ou escrever uma narrativa na mesma.
Entretanto, tal método possui como uma de suas desvantagens a inexistência
de regras que ditem como cada ação deve ser descrita a fim de evitar ambiguidades ou
problemas de clareza quanto à sua compreensão.
3.4.2 Fluxogramas
Outra forma de representar um algoritmo bastante comum é por meio de
representações gráficas, geralmente fluxogramas.
Um fluxograma trata-se de um diagrama composto por várias ações e entidades
representadas em “caixas” de diversos formatos (o formato de cada qual determina o
tipo de ação a ser tomado ali) e setas interligando todas essas caixas de forma a criar-se
um “caminho” com início e fim.
A sequência de ações que deve ser tomada, então, é encontrada “percorrendo-se”
o fluxograma de seu início até o seu fim, sendo então executada cada ação ou teste
como está escrito.
Abaixo, um exemplo de fluxograma:
A principal vantagem da representação gráfica de um algoritmo por meio de um
fluxograma é mais concisa que a descrição narrativa, representando visualmente desvios
e laços.
Entretanto, tal método tem como desvantagem a necessidade de aprender
simbologia necessária para a construção de fluxogramas.
3.4.3 Pseudocódigo (Portugol)
Outra forma de representar um algoritmo é por meio de um pseudocódigo, isto é,
a representação textual das ações por meio de comandos pré-definidos em uma espécie
de linguagem similar a uma linguagem de programação, porém muito mais próxima da
nossa própria.
No Brasil, como nosso idioma é o Português, podemos nos utilizar de um
pseudocódigo conhecido como Português Estruturado, também conhecido por
Portugol.
Abaixo, um exemplo de um pseudocódigo em Portugol para o cálculo da média
de um aluno a partir de suas quatro notas.
programa calculo_de_media;
leia notaA, notaB, notaC, notaD;
media <- (notaA + notaB + notaC + notaD) / 2;
retorne media;
A principal vantagem da adoção de um pseudocódigo como forma de
representar um algoritmo é que a sua transcrição para código-fonte em uma linguagem
de programação qualquer é bastante direta, principalmente quando especificado em
Portugol, uma vez que este apresenta regras, expressões e conceitos muito similares aos
presentes na maioria das linguagens de programação.
A principal desvantagem é que, a fim de utilizar-se corretamente de um
pseudocódigo para representar um algoritmo, temos que aprender todas as regras
daquele pseudocódigo, o que pode ser quase tão complexo quanto aprender uma
linguagem de programação.
3.4.4 Em uma linguagem de programação
E a última forma de representação de um algoritmo que estudaremos aqui é
utilizando-se de uma linguagem de programação tal que possamos elaborar diretamente
o código-fonte do programa que desejamos.
Abaixo, um exemplo de algoritmo escrito na linguagem C efetuando a soma dos
números 3 e 2 e posteriormente a impressão do mesmo.
void main() {
int a;
a = 3 + 2;
printf(“Resultado: %d”, a);
}
A principal vantagem desta forma de representação é bem clara: por meio dela,
já temos o código-fonte do programa que desejamos construir, assim, precisamos
somente compilá-la e construir o executável da aplicação.
A principal desvantagem é que é necessário conhecimentos suficientes de uma
linguagem de programação a fim de escrever o código-fonte da mesma, exigindo assim
muito mais do aprendiz do que as demais formas de representação.
3.5 Vantagens do uso de algoritmos
Deve-se lembrar que um algoritmo, isto é, a descrição das ações a serem
executadas a fim de cumprir uma tarefa, é independente das linguagens de programação.
Isso significa que a partir de um algoritmo deve-se ser capaz de convertê-lo para
qualquer outra linguagem de programação – mesmo quando o mesmo já foi escrito em
uma linguagem de programação!
A adoção de um algoritmo na definição da tarefa facilita a compreensão acerca
da solução adotada, ao descrevê-la na forma de passos seqüenciais não-ambíguos.
Além disso, não há um formalismo rígido sobre como um algoritmo deve ser
escrito, ficando assim a cargo do responsável a escolha pelo método que melhor lhe
convém.
3.6 Elementos fundamentais de um algoritmo
Analisemos agora os elementos que compõem um algoritmo. Para ficar mais
claro do que estamos falando, consideremos como exemplo um algoritmo que, dado um
número N, deve retornar o fatorial de N como solução.
3.6.1 Entrada
São os dados de entrada do algoritmo, toda informação necessária para a
execução correta do mesmo e que deve ser informada pelo usuário do sistema e/ou ser
proveniente de outras fontes externas (como bancos de dados, arquivos, etc.).
No exemplo supracitado, o valor de N será a nossa entrada, necessária para a
realização do cálculo.
3.6.2 Processamento
São os procedimentos utilizados para chegar ao resultado final. Todo algoritmo
pode executar algum tipo de processamento sobre os valores recebidos e então devolver
os novos valores encontrados.
Em nosso exemplo, todo o cálculo necessário para determinar o fatorial de N
deve ser considerado parte do processamento.
3.6.3 Saída
São os dados já processados e prontos para serem enviados ao usuário ou
armazenados em alguma fonte externa.
Em nosso exemplo, o resultado final, isto é, o fatorial de N, é a nossa saída.
Abaixo uma figura ilustrando como isso ocorre em um algoritmo:
Entrada
Processamento
Saída
3.7 Linguagem de programação, compilador e IDE
A fim de melhor facilitar o nosso aprendizado, conheçamos agora três conceitos
importantes para quem está aprendendo a programa: linguagem de programação,
compilador e IDE.
3.7.1 Linguagem de programação
Uma linguagem é um conjunto de regras sintáticas e semânticas com o intuito de
facilitar a comunicação.
No campo da Computação, uma linguagem de programação refere-se ao
conjunto de regras sintáticas e semânticas utilizado para definir um programa de
computador.
3.7.2 Compilador
Programa que, a partir de um código escrito em uma linguagem de programação,
o código-fonte, e cria um programa semanticamente equivalente, porém escrito em
outra linguagem, o código-objeto.
O código-objeto ainda não é o nosso executável final, em código de máquina.
Antes disso, entrará em ação outra ferramenta, o linkeditor (ou ligador, como os
portugueses traduzem tal termo), cuja tarefa é pegar o código-objeto, as bibliotecas
necessárias para a execução do mesmo e vários outros arquivos e parâmetros e
converter tudo em um arquivo executável – agora sim, pronto para a execução em
qualquer máquina com a arquitetura para a qual foi projetado.
Abaixo uma imagem representando todo esse processo:
Lembre-se: um compilador é bem diferente de um interpretador! No caso do
interpretador, não há geração de código-objeto e, portanto, não há também a tarefa de
linkedição. Em vez disso, ao executar-se um programa em um interpretador ele irá
carregar o código-fonte e converter “on the fly” (isto é, durante sua execução, in run
time) cada instrução em uma instrução reconhecível pela máquina tal que possa ser
executada.
3.7.3 IDE
IDE é a abreviatura de Integrated Development Environment – ambiente para
desenvolvimento integrado, em uma tradução livre.
Refere-se a um ambiente integrado onde o desenvolvedor pode organizar todos
os arquivos relacionados ao desenvolvimento de um programa, editá-los, compilá-los e
testar seu programa de forma fácil e rápida.
Antes do uso de IDEs no desenvolvimento, o código-fonte era escrito em
qualquer editor de texto (dessa forma, sem o uso de certos benefícios como
funcionalidades para “auto-completar o código”, verificação de sintaxe em tempo de
edição e outras) e era comum o uso de prompt de linha de comando para as tarefas de
compilação, linkedição, etc.
As IDEs atuais oferecem também muitas facilidades para debugging, isto é,
testes da aplicação a fim de analisar se o seu funcionamento está correto.
Abaixo, uma imagem da IDE do Code::Blocks:
Download