Sei sulla pagina 1di 13

Escola Nacional de Ciências Estatísticas

Curso de Graduação em Estatística


(Bacharelado)

Computação

Unidade VIII:

 Conceitos Avançados sobre


Vetores

Professor: Eduardo Corrêa


Data: 22/10/2007

1
Escola Nacional de Ciências Estatísticas

Introdução

Os programas de computador que produzem informações estatísticas muitas vezes


precisam utilizar vetores para armazenar em memória os dados coletados por uma pesquisa.
Em diversas situações, os dados devem ser classificados (ordenados) para viabilizar o
cálculo dos diferentes índices e medidas. Esta unidade apresenta um algoritmo para a
ordenação de elementos em vetores.

VIII.1 Carga de Vetores

Antes de começar o assunto ordenação de vetores, será apresentado um problema


mais simples. Imagine que você precisa fazer um programa com as seguintes
características: ele deve receber o nome de uma disciplina da ENCE e um conjunto
contendo as notas finais de todos os alunos. Ao final da digitação, o programa deverá
imprimir um relatório que listará todas as notas e indicará quais delas estão acima da média
da turma. O programa deve ser “genérico” o suficiente para atender a qualquer disciplina da
universidade (é sabido que nenhuma disciplina pode ter mais de 100 alunos matriculados).
Neste problema, será necessário usar um vetor para o armazenamento de dados (as
notas finais). No entanto, dependendo da disciplina o vetor será carregado com uma
quantidade diferente de dados (ex: para a disciplina Computação o vetor deverá receber a
nota de 60 alunos, enquanto que, para a disciplina Banco de Dados esse número não irá
passar de 36 alunos). Em resumo, o que ocorre é: conhecemos o limite máximo de
informações que poderão ser armazenadas no vetor, mas esta quantidade de informações
muda para cada disciplina (para ser ainda mais claro: a quantidade exata de notas é
imprevisível, mas está sempre abaixo de 100).
A resolução de um problema deste tipo pode ser feita de duas maneiras. A primeira
delas é permitir com que o usuário utilize um flag para sinalizar que deseja terminar o
processo de digitação (no caso deste problema, basta escolher um valor impossível de nota
final para servir como flag, como –1 ou –999). A segunda maneira (mais simples) é
perguntar a quantidade de informações que serão digitadas, antes de começar a receber os
dados. Os exemplos VIII.1 e VIII.2 ilustram as duas formas de resolver o problema.

PROBLEMA: Construir um programa receba o nome de uma disciplina e a quantidade de


notas finais (a quantidade máxima de informações que pode ser digitada é 100).

Em seguida gere um relatório que liste todas as notas e indique as que estão acima da
média.

2
Escola Nacional de Ciências Estatísticas

EXEMPLO VIII.1 Resolução com o uso de FLAG

program UsaFlag;
var VET_NOTAS: array[1..100] of real; {vetor com as notas}
QTD_NOTAS: integer; {quantidade de notas do vetor}
DISC: string; {nome da disciplina}
MEDIA: real; {média das notas}
SOMA: real; {soma das notas}
AUX: real; {auxiliar: recebe nota da disciplina}
I: integer; {usada no loop for-do}
begin
writeln('Programa Notas Finais');
writeln('=====================');
writeln;

{PASSO 1: recebe o nome da disciplina}


write('Qual o nome da disciplina? ');
readln(DISC);

{PASSO 2: recebe notas finais até o usuário desejar encerrar}


QTD_NOTAS:=0;
SOMA := 0;
repeat
writeln('Digite uma nota ou –999 para encerrar: ');
readln(aux); {armazena inicialmente a nota em AUX}

if (aux >= 0) then {coloca a nota no vetor apenas se ela tiver}


begin {valor maior ou igual a zero!}

QTD_NOTAS:= QTD_NOTAS + 1; {incrementa a quantidade de notas}

VET_NOTAS[QTD_NOTAS] := aux; {coloca a nota no vetor,


na posição adequada}

SOMA := SOMA + aux; {incrementa o somatório das notas –


necessário para o cálculo da média}
end;
until (QTD_NOTAS = 100) or (AUX = -999); {encerra o laço caso o
usuário tenha digitado 100
notas ou tenha digitado
o flag de saída}
{PASSO 3: calcula a média}
if (QTD_NOTAS > 0) then MEDIA := SOMA / QTD_NOTAS;

{PASSO4: imprime o relatório}


writeln('* * DISCIPLINA: ', DISC,' - MEDIA FINAL = ',MEDIA:2:2);
for I:=1 to QTD_NOTAS do
begin
write('Nota ',I,' = ',VET_NOTAS[I]:2:2);
if (VET_NOTAS[I] > MEDIA) then
write(' ** ACIMA DA MEDIA ');
writeln;
end;
readln;
end.

3
Escola Nacional de Ciências Estatísticas

A Figura VIII.1 apresenta uma tela com a execução do programa:

Figura VIII.1– Execução do programa das médias resolvido com flag

O principal “segredo” da resolução do programa está no uso da variável


QTD_NOTAS com duas finalidades. Durante o laço repeat-until (PASSO 2), a
QTD_NOTAS é usada para colocar cada nota numa posição distinta do vetor. Após o fim
desse laço, o valor de QTD_NOTAS será igual ao total de notas armazenado no vetor. Com
isso, torna-se possível usar essa variável para realizar o cálculo da média da turma (PASSO
3) e também para produzir o relatório desejado pelo programa (veja que QTD_NOTAS é
usada como limite superior do laço for-do apresentado no PASSO 4).

EXEMPLO VIII.2 Resolução com o uso de PERGUNTA AO USUÁRIO

program UsaPergunta;
var VET_NOTAS: array[1..100] of real; {vetor com as notas}
QTD_NOTAS: integer; {quantidade de notas do vetor}
DISC: string; {nome da disciplina}
MEDIA: real; {média das notas}
SOMA: real; {soma das notas}
AUX: real; {auxiliar: recebe nota da disciplina}
I: integer; {usada para armazenar notas no vetor e no loop
for-do}
begin
writeln('Programa Notas Finais');
writeln('====================='); writeln;

{PASSO 1: recebe o nome da disciplina}


write('Qual o nome da disciplina? ');
readln(DISC);

4
Escola Nacional de Ciências Estatísticas

{PASSO 2: pergunta o total de notas. Note que o loop “prende” o


usuário até que ele digite um valor entre 1 e 100}

repeat
write('Qual eh o total de notas a ser digitado (MAX = 100)? ');
readln(QTD_NOTAS);
if (QTD_NOTAS < 1) or (QTD_NOTAS > 100) then
writeln('VALOR INVALIDO!');
until (QTD_NOTAS <= 100) and (QTD_NOTAS > 0);

{PASSO 3: recebe notas finais até atingir


o total especificado pelo usuário}
SOMA := 0;
I:=0;
repeat
writeln('Digite a nota ',I+1,' : ');
readln(aux); {armazena inicialmente a nota em AUX}

if (aux >= 0) then {coloca a nota no vetor apenas se ela tiver}


begin {valor maior ou igual a zero!}

I:= I + 1; {incrementa a quantidade de notas}

VET_NOTAS[I] := aux; {coloca a nota no vetor na posição adequada}

SOMA := SOMA + aux; {incrementa o somatório das notas –


necessário para o cálculo da média}
end;
until (I = QTD_NOTAS); {encerra o laço caso o usuário tenha digitado o
total de notas que especificou}

{PASSO 4: calcula a média – não preciso mais ver se QTD_NOTAS é zero,


pois já impedi isso no passo 2}
MEDIA := SOMA / QTD_NOTAS;

{PASSO 5: imprime o relatório}


writeln('* * DISCIPLINA: ', DISC,' - MEDIA FINAL = ',MEDIA:2:2);
for I:=1 to QTD_NOTAS do
begin
write('Nota ',I,' = ',VET_NOTAS[I]:2:2);
if (VET_NOTAS[I] > MEDIA) then
write(' ** ACIMA DA MEDIA ');
writeln;
end;
readln;
end.

A Figura VIII.2 apresenta uma tela com a execução do programa:

5
Escola Nacional de Ciências Estatísticas

Figura VIII.2– Execução do programa das médias resolvido com pergunta ao usuário.

No caso desse programa, a idéia principal foi a de garantir com que o usuário
digitasse um valor correto (entre 1 e 100) para a quantidade de notas no PASSO 2. Depois
disso o problema pôde ser resolvido normalmente, de uma forma muito similar à utilizada
no Exemplo VIII.1.

VIII.2 Ordenação de Vetores

Na Estatística, existem muitos problemas que podem ser resolvidos apenas quando
o conjunto de dados a ser analisado estiver classificado de alguma maneira. Um exemplo
típico é a obtenção da mediana de uma distribuição, onde é preciso dispor os dados em
ordem de tamanho para que seja possível encontrar “o ponto do meio” (veja o quadro
abaixo).

CALCULO DA MEDIANA

Recorde que, a posição do valor da mediana é dada pela fórmula (N + 1) / 2, onde N representa o
número de casos da distribuição. Quando temos um número ímpar de observações, a mediana é o
caso que recai exatamente no meio da distribuição:

11, 12, 13, 16, 17, 20, 25

De acordo com a fórmula (7 + 1) / 2 = 4, temos que a mediana é 16 (o quarto valor na


distribuição(. Quando temos um número para de valores, haverá dois casos médios:

11, 12, 13, 16, 17, 20, 25, 30

Pela fórmula (8 + 1) / 2 = 4,5, a posição da mediana recai a meio caminho entre o quarto e o quinto
valor. Nesse caso a mediana é igual a (16 + 17) / 2 = 16,5.

6
Escola Nacional de Ciências Estatísticas

Existem muitos outros problemas práticos que precisam de casos ordenados ou que,
ao menos, tornam-se mais fáceis de serem resolvidos quando as observações estão
ordenadas. Exemplos:

• Determinar os 10 maiores valores de uma distribuição.

• Determinar os 5 menores valores de uma distribuição.

• Calcular a Moda de uma distribuição.

• Localizar a menor nota cujo valor esteja acima da média da turma.

Na prática, não é possível impor ao usuário de um programa de computador para


que ele entre com um conjunto de dados de forma ordenada. A pessoa provavelmente
ficaria com muita raiva do programa que pedisse isso para ela! Resta-nos, então a seguinte
alternativa: permitir com que o usuário entre com os dados numa ordem qualquer e, depois
do processo de carga do vetor, executar um algoritmo de ordenação1. Um algoritmo de
ordenação de vetores representa um pequeno trecho de programa que é capaz analisar os
dados de um vetor e realizar múltiplas iterações até que consiga colocar estes dados de
maneira ordenada (ou seja, colocar o menor valor no subscrito 1, o segundo menor valor no
subscrito 2, e assim sucessivamente). A Figura VIII.3 ilustra o estado de um vetor V antes
e depois de ser classificado por um algoritmo de ordenação.

Figura VIII.3– Vetor V: antes e depois de ser classificado.

1
Uma outra alternativa consiste em usar um algoritmo que já insira os dados de forma ordenada, no entanto
esse processo é mais custoso e complicado.

7
Escola Nacional de Ciências Estatísticas

Existem diversos algoritmos para a classificação de vetores propostos na literatura.


Nesta unidade apresentaremos apenas o algoritmo Bubble Sort (conhecido como “algoritmo
da bolha”) por ele ser o mais simples e didático de todos2. O algoritmo Bubble Sort utiliza a
seguinte idéia:

• Comparar os elementos de um vetor dois a dois e ir “empurrando” os maiores


valores para as últimas posições do vetor, até que este esteja classificado.

• O algoritmo é executado em diversas fases. Para um vetor de tamanho N, são


executadas N-1 fases (ou seja, para ordenar um vetor de tamanho 100, é preciso
executar 99 fases).

• Ao final da primeira fase, o maior elemento terá sido empurrado para o mais alta
subscrito do vetor (subscrito N). Com isso, na segunda fase, podemos reduzir a
faixa do vetor a ser analisada (agora poderemos analisar da posição 1 até a
posição N-1). Ao final da segunda fase, o segundo maior elemento terá sido
empurrado para a penúltima posição do vetor. Com isso, a partir da terceira fase,
podemos reduzir novamente a faixa do vetor a ser analisada (agora podemos
examinar do subscrito 1 até o subscrito N-2).

O exemplo a seguir demonstra, passo a passo, o funcionamento do algoritmo


Bubble Sort. Examine-o com cuidado e atenção para que você possa entender a idéia deste
algoritmo.

Vetor original (da forma como foi digitado pelo usuário).


1 2 3 4 5
V 55 41 39 65 20

1a FASE – Será preciso analisar todos os elementos. No fim desta fase, o valor 65 será
empurrado para a quinta posição do vetor.

ITERAÇÃO 1.1: Compara-se 55 (valor da posição 1) com 41 (valor da posição 2). Como 55
é maior do que 41, os dois são trocados de posição.
1 2 3 4 5
V 55 41 39 65 20

ITERAÇÃO 1.2: Compara-se 55 (valor da posição 2) com 39 (valor da posição 3). 55 > 39,
então os dois são trocados de posição.
2
Na prática, o algoritmo Bubble Sort apresenta um desempenho muito inferior ao de outros algoritmos de
ordenação, como o QuickSort, por exemplo. Em contrapartida, ele é muito mais simples de ser entendido. Por
esta razão costuma ser introduzido nos cursos de iniciais de programação.

8
Escola Nacional de Ciências Estatísticas

1 2 3 4 5
V 41 55 39 65 20

ITERAÇÃO 1.3: Compara-se 55 (valor da posição 3) com 65 (valor da posição 4). Como 55
é menor do que 65, os dois elementos NÃO são trocados de lugar!
1 2 3 4 5
V 41 39 55 65 20

ITERAÇÃO 1.4: Compara-se 65 (valor da posição 4) com 20 (valor da posição 5). 65 > 20,
então os dois são trocados de posição.
1 2 3 4 5
V 41 39 55 65 20

RESULTADO AO FINAL DA FASE 1:

1 2 3 4 5
V 41 39 55 20 65

2a FASE – Agora eu não preciso analisar o último subscrito do vetor, pois já sei que ele
contém o maior elemento.

ITERAÇÃO 2.1: Comparação entre 41 (valor da posição 1) e 39 (valor da posição 2). 41 > 39
- são trocados de posição.
1 2 3 4 5
V 41 39 55 20 65

ITERAÇÃO 2.2: Comparação de 41 com 55. 41 < 55 - NÃO são trocados de posição.
1 2 3 4 5
V 39 41 55 20 65

ITERAÇÃO 2.3: Comparação de 55 com 20. 55 > 20 - são trocados de posição.


1 2 3 4 5
V 39 41 55 20 65

RESULTADO AO FINAL DA FASE 2:

9
Escola Nacional de Ciências Estatísticas
1 2 3 4 5
V 39 41 20 55 65

3a FASE – Não é preciso analisar os dois últimos subscritos do vetor.

ITERAÇÃO 3.1: Comparação entre 39 e 41. 39 > 41 – NÃO são trocados de posição.
1 2 3 4 5
V 39 41 20 55 65

ITERAÇÃO 3.2: Comparação entre 41 e 20. 41 > 20 –são trocados de posição.


1 2 3 4 5
V 39 41 20 55 65

RESULTADO AO FINAL DA FASE 3:

1 2 3 4 5
V 39 20 41 55 65

4a FASE – ÚLTIMA FASE – é preciso comparar apenas os dois primeiros elementos do vetor.

ITERAÇÃO 4.1: Comparação entre 39 e 21. 39 > 21 –são trocados de posição.


1 2 3 4 5
V 39 20 41 55 65

RESULTADO AO FINAL DA FASE 4 – VETOR TOTALMENTE ORDENADO

1 2 3 4 5
V 20 39 41 55 65

Observações:

1. Para ordenar o vetor de tamanho 5, foi preciso executar um total de 4 fases. Para
um vetor de tamanho N, o algoritmo executa N – 1 fases.

2. Dentro de uma fase F, sempre são realizadas um total de N – F iterações. Dentro


da fase 1, foram executadas 5 – 1 = 4 iterações. Dentro da fase 4, foi executada
5 – 4 = 1 iteração.

10
Escola Nacional de Ciências Estatísticas

A Figura VIII.4 apresenta o modelo para implementação do algoritmo Bubble Sort


em Pascal. A seguir apresenta-se uma breve explicação sobre o seu funcionamento (o
algoritmo simplesmente faz o que foi descrito no exemplo mostrado nas páginas 8, 9 e 10).

for FASE := 1 to N – 1 do {laço externo – executa N-1 fases}

for I:=1 to N – FASE do {laço interno – iterações de cada fase}

if V[I] > V[I+1] then {se elemento da esquerda é maior}


begin {do que elemento da direita,}
{é preciso trocar as posições}
aux:= V[I];

V[I]:= V[I+1]; {a troca é feita com o uso de uma}


{variável auxiliar}
V[I+1] := aux;

end;
Figura VIII.4 – Bubble Sort implementado em Pascal

No modelo acima, estamos supondo a ordenação de um vetor V que possui tamanho


N. O algoritmo começa com um comando for-do externo que define a execução de N-1
fases (linha 1). Subordinado ao for-do externo, encontra-se um outro for-do, que define o
número de iterações dentro de cada fase (sempre N – FASE iterações, linha 2). Dentro de
cada iteração, um elemento do vetor é comparado com o seu vizinho e os conteúdos são
trocados quando o valor do elemento da esquerda é maior do que o valor do elemento da
direita (linhas 5 a 7). Observações Importantes:

1. A variável aux deve ser do mesmo tipo de dado do vetor a ser ordenado. Se
estamos ordenando um vetor de reais, aux deve ser do tipo real. Se for um vetor
de inteiros, aux tem que ser do tipo inteiro.

2. x

EXEMPLO VIII.3 – APLICAÇÃO DA ORDENAÇÃO DE VETORES

Crie um programa que leia uma distribuição composta por, no máximo, 1000 observações e
que determine o valor da mediana.

program CalculaMediana;
const MAX = 1000;
var VET: array[1..MAX] of real; {vetor com as observações}
N, I, FASE: integer; {variáveis usadas pelo BubbleSort}
aux: real; {auxliar para a troca de elementos no
Bubble Sort}
MEDIANA: real;
begin
writeln('Programa Mediana');

11
Escola Nacional de Ciências Estatísticas
writeln;

{PASSO 1: pergunta o total de observações}


repeat
write('Quantos valores serao digitados (MAXIMO = 1000)? ');
readln(N);
if (N < 1) or (N > MAX) then
writeln('VALOR INVALIDO!');
until (N <= MAX) and (N > 1);

{passo 2 – carregar os dados no vetor}


writeln('Digite ',N, ' valores');
for I:=1 to N do
begin
write('Valor ',I, '= '); readln(VET[I]);
end;

{passo 3 – para calcular a mediana, é preciso que os dados estejam


ordenados. Então vamos aplicar o Bubble Sort}

for FASE := 1 to N – 1 do
for I:=1 to N – FASE do
if VET[I] > VET[I+1] then
begin
aux:= VET[I];
VET[I]:= VET[I+1];
VET[I+1] := aux;
end;

{passo 4 – acha a Mediana. Depende de N ser par ou impar!}

I := (N + 1) DIV 2;
if (N MOD 2 = 1) then {N é impar}
MEDIANA := VET[I]
else {N é par}
MEDIANA := (VET[I] + VET[I+1]) / 2;

writeln('Mediana = ',MEDIANA:6:2);

readln;

end.

12
Escola Nacional de Ciências Estatísticas

TRABALHO EM GRUPO – ORDENAÇÃO DE VETORES

1) (3,0 PONTOS) Crie um programa que leia N números reais (10 ≤ N ≤ 500) e armazene em um
vetor. Em seguida ordene o vetor e imprima os números localizados nos 5 primeiros subscritos e
os números localizados nos 5 últimos subscritos do vetor.

2) (7,0 PONTOS) CÁLCULO DO MODA: A moda é o valor mais freqüente, mais típico em uma
distribuição. Por exemplo:

• Se em uma dada universidade, Engenharia é o curso de maior procura, ele representa


a moda.

• No conjunto de valores 1, 2, 3, 1, 1, 6, 4, 5, 1, 4, 1, 4, 3, a moda é 1, porque é o valor


que ocorre com maior freqüência.

Faça um programa que leia uma distribuição com, no máximo, 400 valores inteiros e que
determine qual é a moda.

Observações:

1. Antes de fazer o programa, elabore um algoritmo que descreva os passos da sua idéia
para a resolução do problema. Não tente sair programando direto! É sempre melhor
projetar uma solução antes, com o uso de diagramas e da descrição dos passos em
Português.

2. A resolução deste problema torna-se mais simples se você ordenar o conjunto de valores
que compõem a distribuição.

3. Seu programa deve ser esperto o suficiente para identificar distribuições que contenham 2
ou mais modas. Exemplo: no conjunto 6, 6, 7, 2, 6, 1, 3, 2, 2, 4 os valores 2 e 6 ocorrem
ambos com a maior freqüência. Portanto, trata-se de uma distribuição com duas modas
(distribuição bimodal).

13

Potrebbero piacerti anche