Listas e Estruturas
Pedro Barahona
DI/FCT/UNL
Maio 2004
11/12 de Maio de 2004
Estruturas
1
Processamento de Informação Alfanumérica
• Como visto anteriormente, muita informação alfanumérica
está registada em ficheiros. Numa base de dados da empresa,
são mantidos ficheiros com informação sobre os empregados
da empresa.
• O processamento dessa informação pode ser feita através da
leitura e escrita de ficheiros. No entanto estas operações são
muito demoradas em geral, e seria preferível manter a
informação em memória.
cod
610
825
316
34
723
11/12 de Maio de 2004
nome
Paulo Fernandes Lopes
Pedro Vieira
Marta Costa Martins
Rui Vasco Pereira
Jorge Barata
Estruturas
vencimento
data
2341.36
989.24
1389.17
5310.32
767.26
15/04/1996
25/06/1999
05/01/1992
15/04/1996
03/09/2002
2
Processamento de Informação Alfanumérica
• Podemos considerar que a informação destes ficheiros
corresponde a uma tabela. Esta tabela é constituída por uma
sequência de “registos”, um em cada linha.
• Se toda a informação fosse numérica, isto é se cada registo
tivesse n “campos”, ela poderia ser guardada numa matriz
com m linhas, uma linha para cada registo de n posições.
• Em Octave, existe um problema: uma posição de uma matriz
não pode ser ocupada por uma cadeia de caracteres!
cod
610
825
316
34
723
11/12 de Maio de 2004
nome
Paulo Fernandes Lopes
Pedro Vieira
Marta Costa Martins
Rui Vasco Pereira
Jorge Barata
Estruturas
vencimento
data
2341.36
989.24
1389.17
5310.32
767.26
15/04/1996
25/06/1999
05/01/1992
15/04/1996
03/09/2002
3
Processamento de Informação Alfanumérica
• Desta forma a informação de uma tabela alfanumérica não
pode ser guardada como uma matriz. Vamos ver como se
podem ultrapassar estes problemas em Octave, fazendo-o em
duas “fases”:
– Como representar um registo heterogéneo, com vários
campos de diferentes tipos, alguns alfanuméricos.
– Como armazenar e aceder a vários destes registos
heterogéneos.
cod
610
825
316
34
723
11/12 de Maio de 2004
nome
Paulo Fernandes Lopes
Pedro Vieira
Marta Costa Martins
Rui Vasco Pereira
Jorge Barata
Estruturas
vencimento
data
2341.36
989.24
1389.17
5310.32
767.26
15/04/1996
25/06/1999
05/01/1992
15/04/1996
03/09/2002
4
Estruturas
• Vectores e Matrizes são muito úteis quando os dados são todos
do mesmo tipo (no Octave, de qualquer tipo numérico).
• No entanto, em muitos casos, a informação que se pretende
agrupar com um só identificador não é do mesmo tipo.
• Por exemplo, um empregado duma empresa pode ter
associado a seguinte informação
– Um código (um número?)
– Um nome (uma cadeia de caracteres)
– Um vencimento (um decimal)
– Uma data de entrada (uma cadeia, ou 3 campos numéricos,
para o dia, mês e ano)
cod
nome
610 Paulo Fernandes Lopes
11/12 de Maio de 2004
Estruturas
venc
2341.36
data
15/04/1996
5
Estruturas
• As várias linguagens de programação
permitem o
agrupamento destes dados heterogéneos, com um mesmo
identificador de uma forma variada (records no Pascal, Struct
em C, ...)
• O Octave adopta uma designação semelhante à do C,
denominando estes agrupamentos como estruturas.
• Consideremos pois o caso do empregado abaixo, em que
gostaríamos de agregar toda a informação numa única
variável, do tipo estrutura, que denotaremos como emp_610.
emp_610 =
11/12 de Maio de 2004
cod
nome
610 Paulo Fernandes Lopes
Estruturas
venc
2341.36
data
15/04/1996
6
Estruturas
• As estruturas são compostas por vários campos, cada um
com um nome. Na estrutura para representação da
informação de empregados, consideraremos os campos
abixo, que guardam a informação “esperada”
– cod: o código do empregado
– nome: o nome do empregado
– venc: o vencimento do empregado
– data: a data de entrada do empregado na empresa.
emp_610 =
11/12 de Maio de 2004
cod
nome
610 Paulo Fernandes Lopes
Estruturas
venc
2341.36
data
15/04/1996
7
Estruturas
• Uma vez definidos os nomes dos campos da estrutura,
podemos atribuir-lhe os valores pretendidos.
• O acesso a um campo da estrutura é feito fazendo suceder ao
nome da estarutura o nome do campo pretendido, separado
por um ponto (‘.’).
• Por exemplo, a atribuição dos 4 valores dos campos pode ser
feita pelas seguintes atribuições:
emp_610.cod = 610;
emp_610.nome = “Paulo Fernandes Lopes”;
emp_610.venc = 2341.36;
emp_610.data=“15/04/1996”;
emp_610 =
11/12 de Maio de 2004
cod
nome
610 Paulo Fernandes Lopes
Estruturas
venc
2341.36
data
15/04/1996
8
Estruturas
• De notar que os campos de uma estrutura não são ordenados,
e podem ser preenchidos por qualquer ordem.
• Assim a estrutura que temos referido
emp_610 =
cod
nome
610 Paulo Fernandes Lopes
venc
2341.36
data
15/04/1996
pode ser inicializada quer com a sequência de instruções
empregado.data=“15/04/1996”;
empregado.cod = 610;
empregado.nome = “Paulo Fernandes Lopes”;
empregado.venc = 2341.36;
ou com outra sequeência
empregado.venc = 2341.36;
empregado.cod = 610;
empregado.data=“15/04/1996”;
empregado.nome = “Paulo Fernandes Lopes”;
11/12 de Maio de 2004
Estruturas
9
Estruturas
• Uma vez agrupados os vários items de informação numa só
variável do tipo estrutura, podemos referir alguns campos
depois de verificar outros.
• Por exemplo, dados vários empregados com o tipo referido,
indicar qual o nome dos que ganham mais de 1000 euros.
• Na sintaxe do Octave, tal poderia ser feito através da
instrução condicional
if emp_610.venc > 1000
then disp(emp_610.nome)
endif
• No entanto este tipo de processamento só é verdadeiramente
útil se tivermos a possibilidade de aceder a todos os
empregados de uma forma genérica.
11/12 de Maio de 2004
Estruturas
10
Estruturas
• Por exemplo, se tivessemos uma tabela com várias linhas,
com códigos na primeira coluna e vencimentos na 2ª coluna,
poderíamos apresentar os códigos dos empregados com
vencimento superior a 1000 euros através da seguinte
1
2
instrução iterativa:
for i = 1:n
if tabela(i,2) > 1000
then disp(tabela(i,1))
endif
endfor;
1
2
3
4
5
...
610
825
316
34
723
...
2341.36
989.24
1389.17
5310.32
767.26
...
• Por analogia, o que é necessário é poder aceder a uma
sequência de (1 a n) estruturas do tipo da do empregado.
• Em Octave, essa sequência pode ser implementada através
de listas.
11/12 de Maio de 2004
Estruturas
11
Listas
• Uma lista é uma sequência de dados do mesmo tipo, simples
ou complexo, para as quais estão definidas as operações de:
• Criação: list(elem_1, elem_2, ..., elem_k)
– Cria uma lista, com os elementos de 1 a k (ou uma lista
vazia se k = 0)
• Acrescento: append(nome_lista,elem_1, ...,elem_k)
– Acrescenta os os elementos de 1 a k à lista com o nome
indicado no 1º argumento
• Acesso: nth(nome_lista, k)
– Acede ao k-ésimo elemento da lista. De notar que esse
elemento pode ser uma estrutura arbitrariamente
complexa.
11/12 de Maio de 2004
Estruturas
12
Listas
• Para ilustrar estes conceitos, vamos ler um ficheiro com
informação sobre empregados e criar uma lista com essa
informação.
• A instrução principal consiste em criar uma estrutura, emp, e
atribuir-lhe os valores lidos do ficheiro (a formatação dos
campos é feita como anteriormente).
[emp.cod, emp.nome, emp.venc, emp.data, count] =
fscanf(f_aux,"%i%s%f%s","C");
• Para além destas instruções, são necessárias instruções para
inicializar a lista e para a ir acrescentando com os
empregados lidos. O número de empregados também é
computado.
11/12 de Maio de 2004
Estruturas
13
Listas
• Eis
o
programa completo, que cria uma lista,
tab_empregados, com a informação sobre os empregados
inicialmente no ficheiro “empresa_aux_var.txt”.
[f_aux, msg] = fopen("empresa_aux_var.txt", "r");
tab_empregados = list(); n = 0;
[emp.cod,emp.nome,emp.venc,emp.data, count] =
fscanf(f_aux,"%i%s%f%s","C");
while !feof(f_aux)
n = n+1;
tab_empregados = append(tab_empregados, emp);
[emp.cod,emp.nome,emp.venc,emp.data, count] =
fscanf(f_aux,"%i%s%f%s","C");
endwhile;
fclose(f_aux);
11/12 de Maio de 2004
Estruturas
14
Listas
• A partir deste momento, todo o processamento da
informação sobre os empregados pode ser feito sem leitura
do ficheiro, mas apenas por acesso à lista
“tab_empregados”.
• Vamos ilustrar esta situação através do cálculo da média dos
vencimentos dos empregados.
• Começamos por apresentar a versão que obriga à leitura do
ficheiro, mostrando seguidamente a versão que utiliza a lista
já criada.
11/12 de Maio de 2004
Estruturas
15
Listas
• O programa que lê o ficheiro é idêntico ao apresentado
anteriormente.
[f_aux, msg] = fopen("empresa_aux_var.txt", "r");
[cod,nome, venc, data, count] =
fscanf(f_aux,"%i%s%f%s","C");
i = 0; total = 0;
while !feof(f_aux)
i = i+1; total = total +venc;
[cod,nome, venc, data, count] =
fscanf(f_aux,"%i%s%f%s","C");
endwhile;
printf("o total dos vencimentos é de %7.2f \n",
total);
printf("a média dos vencimentos é de %7.2f \n",
total/i);
fclose(f_aux);
11/12 de Maio de 2004
Estruturas
16
Listas
• Se já tiver sido lida a informação dos empregados para a lista
“tab_empregados”, com n elementos, ela pode ser acedida
directamente, sem necessidade de nova leitura do ficheiro.
total = 0;
for i = 1:n
total = total + nth(tab_empregados,i).venc;
endfor;
printf("o total de vencimentos é %7.2f \n“, total);
printf(“
e a sua média é %7.2f \n", total/n);
11/12 de Maio de 2004
Estruturas
17
Listas
• Igualmente se podem escrever o nome e vencimento dos
empregados que ganham mais de 1000 euros, sem necessidade de
leitura do ficheiro, mas apenas usando a mesma lista
“tab_empregados”, com n elementos.
printf("Lista de empregados com mais de 1000 €: \n");
for i = 1:n
emp = nth(tab_empregados,i);
if emp.venc > 1000
printf("\t%s\t%7.2f\t\n",emp.nome,emp.venc);
endif;
endfor;
11/12 de Maio de 2004
Estruturas
18
Estruturas e Listas em Funções
• Estruturas e listas podem ser retornadas como resultado de uma
função. Por exemplo, a leitura de um ficheiro com o formato
considerado pode ser feita pela função (que também retorna o
número de elementos):
function [t, n] = ler_tabela(ficheiro);
[f_aux, msg] = fopen(ficheiro, "r");
tab_empregados = list(); n = 0;
[emp.cod,emp.nome,emp.venc,emp.data, count] =
fscanf(f_aux,"%i%s%f%s","C");
while !feof(f_aux)
n = n+1;
tab_empregados = append(tab_empregados, emp);
[emp.cod,emp.nome,emp.venc,emp.data, count] =
fscanf(f_aux,"%i%s%f%s","C");
endwhile;
fclose(f_aux); t = tab_empregados;
endfunction;
11/12 de Maio de 2004
Estruturas
19
Download

listas