190 likes | 279 Views
Listas e Estruturas. Pedro Barahona DI/FCT/UNL Maio 2004. 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.
E N D
Listas e Estruturas Pedro Barahona DI/FCT/UNL Maio 2004 Estruturas
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. Estruturas
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! Estruturas
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. Estruturas
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) Estruturas
emp_610 = 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. Estruturas
emp_610 = 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. Estruturas
emp_610 = 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”; Estruturas
emp_610 = 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 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”; Estruturas
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. Estruturas
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 instrução iterativa: for i = 1:n if tabela(i,2) > 1000 then disp(tabela(i,1)) endif endfor; • 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. Estruturas
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. Estruturas
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. Estruturas
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); Estruturas
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. Estruturas
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); Estruturas
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); Estruturas
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; Estruturas
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; Estruturas