A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Vectores (e Listas) : Pesquisa e Ordenação Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2007/2008 21 Maio 20081Vectores.

Apresentações semelhantes


Apresentação em tema: "Vectores (e Listas) : Pesquisa e Ordenação Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2007/2008 21 Maio 20081Vectores."— Transcrição da apresentação:

1 Vectores (e Listas) : Pesquisa e Ordenação Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2007/ Maio 20081Vectores (e Listas): Pesquisa e Ordenação

2 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 2 Leitura para Vectores / Listas de Estruturas Para ilustrar o conceito de vectores/listas de estruturas (para versões Octave posteriores/anteriores a 3.0), vamos considerar o anterior ficheiro com informação sobre empregados e criar uma lista/vector com essa informação. Nota: Assume-se que no ficheiro (empresa_aux.txt) os campos são separados por tabs horizontais e que os espaços dentro dos nomes já foram substituidos por espaços especiais (non-break spaces). Como anteriormente, a cada linha do ficheiro corresponde uma estrutura, emp, com os campos cod, nome, venc e data. Por exemplo,

3 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 3 Vectores – Substituição (Octave 3.0 e posteriores) A leitura dos vários campos de uma estrutura pode ser feita como anteriormente. Um programa, que cria uma vector de estruturas, vec_emps, com a informação sobre os empregados do ficheiro empresa_aux.txt, é o seguinte: [f_aux, msg] = fopen("empresa_aux.txt", "r"); 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; vec_emps(n) = emp; [emp.cod,emp.nome,emp.venc,emp.data, count] = fscanf(f_aux,"%i%s%f%s","C"); endwhile; fclose(f_aux);

4 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 4 Listas – Substituição (versões Octave anteriores a 3.0) A mesma leitura para uma lista de empregados é indicado abaixo (para versões Octave anteriores a 3.0). O programa cria uma lista, lista_emps, com a informação sobre os empregados do ficheiro empresa_aux.txt: [f_aux, msg] = fopen("empresa_aux.txt", "r"); lista_emps = 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; lista_emps = append(lista_emps, emp); [emp.cod,emp.nome,emp.venc,emp.data, count] = fscanf(f_aux,"%i%s%f%s","C"); endwhile; fclose(f_aux);

5 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 5 Estruturas em Funções (Octave 3.0 e posteriores) Estruturas (Octave 3.0 e posteriores) podem ser retornadas como resultado de uma função. Por exemplo, a função abaixo retorna a lista anterior e o número dos seus elementos, (se chamada com o ficheiro de nome empresa_aux.txt) function [vec_emps, n] = ler_lista_emps(fname); [f_aux, msg] = fopen(fname, "r"); 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; vec_emps(n) = emp; [emp.cod,emp.nome,emp.venc,emp.data, count] = fscanf(f_aux,"%i%s%f%s","C"); endwhile; fclose(f_aux); endfunction;

6 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 6 Listas em Funções (versões Octave anteriores a 3.0) Listas de estruturas (versões Octave anteriores a 3.0) podem também ser retornadas como resultado de uma função. Por exemplo, a função abaixo usa listas em vez dos vectores de estruturas anteriores: function [lista_emps, n] = ler_lista_emps(fname); [f_aux, msg] = fopen(fname, "r"); lista_emps = 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; lista_emps = append(lista_emps, emp); [emp.cod,emp.nome,emp.venc,emp.data, count] = fscanf(f_aux,"%i%s%f%s","C"); endwhile; fclose(f_aux); endfunction;

7 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 7 Processamento de Vectores de Estruturas A partir deste momento, todo o processamento da informação sobre os empregados pode ser feito sem leitura do ficheiro, mas apenas por acesso ao vector vec_emps. Vamos ilustrar esta situação em 3 problemas: –Cálculo da média dos vencimentos dos empregados. –Selecção dos empregados com o nome Paulo –Ordenação dos empregados por ordem crescente de antiguidade

8 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 8 Cálculo de Médias em Vectores de Estruturas (Octave 3.0 e posteriores) Uma vez lida a informação dos empregados para o vector vec_emps, ela pode ser acedida directamente e passada como parâmetros de entrada em funções. Assim o cálculo do total e da média dos vencimentos é feito pela chamada da função vencimentos, definida abaixo e chamada com o parâmetro vec_emps. Por exemplo, na instrução [m,t] = vencimentos(vec_emps) function [media, total] = vencimentos(vec_x); total = 0; n = length(vec_x) for i = 1:n total = total + vec_x(i).venc; endfor; media = total / n; % printf("o total de vencimentos é %7.2f \n, total); % printf( e a sua média é %7.2f \n", total/n); endfunction;

9 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 9 Cálculo de Médias em Listas (versões Octave anteriores a 3.0) A função anterior pode ser adaptada para listas de estruturas. Uma vez lida a informação dos empregados para a lista lista_emps, ela pode ser acedida directamente e passada como parâmetros de entrada em funções. Assim o cálculo do total e da média dos vencimentos é feito pela chamada da função vencimentos, definida abaixo e chamada com o parâmetro lista_emps. Por exemplo, na instrução [m,t] = vencimentos(lista_emps) function [media, total] = vencimentos(lista); total = 0; n = length(lista) for i = 1:n total = total + nth(lista,i).venc; endfor; media = total / n; % printf("o total de vencimentos é %7.2f \n, total); % printf( e a sua média é %7.2f \n", total/n); endfunction;

10 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 10 Selecção de Elementos em Vectores de Estruturas (Octave 3.0 e posteriores) Igualmente se podem seleccionar os elementos de um vector de estruturas que satisfazem um certo critério. No exemplo abaixo os empregados cujo vencimento é superior a um dado valor são seleccionados e organizados num vector, emps, que é o resultado da função vencimento_maior. Estes empregados podem ser obtidos pela chamada da função emps_mais_de_1000 = vencimento_maior(vec_emps, 1000) function emps = vencimento_maior(vec_x, valor); k = 0; for i = 1:length(lista) if lista(i).venc > valor k = k + 1; emps(k) = lista(i); endif; endfor; endfunction;

11 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 11 Selecção de Elementos em Listas (Octave 3.0 e posteriores) O critério utilizado para seleccionar os elementos de um vector de estruturas é arbitrário, podendo ser naturalmente outro. No exemplo abaixo são seleccionados, e retornados como resultado da função emps_com_nome, os empregados que têm uma dada palavra no seu nome. Por exemplo, os empregados cujo nome inclui a palavra Paulo são retornados pela chamada da função paulos = emps_com_nome(vec_emps, Paulo) function emps = emps_com_nome(vec_x, nome); k = 0; for i = 1:length(lista) emp = vec_x(i); if index(toupper(emp.nome),toupper(nome))> 0 k = k + 1; emps(k) = emp; endif; endfor; endfunction;

12 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 12 Selecção de Elementos em Listas (versões Octave anteriores a 3.0) As funções anteriores podem ser adaptadas para listas de estruturas: function emps = vencimento_maior(lista, valor); emps = list(); for i = 1:length(lista) emp = nth(lista,i); if emp.venc > valor emps = append(emps, emp); endif; endfor; endfunction; function emps = emps_com_nome(lista, nome); emps = list(); for i = 1:length(lista) emp = nth(lista,i); if index(toupper(emp.nome),toupper(nome))> 0 emps = append(emps, emp); endif; endfor; endfunction;

13 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 13 Ordenação de Listas e Vectores As estruturas de dados lineares (nomeadamente listas e vectores) são frequentemente armazenadas de uma forma ordenada. A ordenação facilita, a pesquisa de informação. Como veremos, numa lista ordenada com n elementos a procura de um elemento pode ser feito com log 2 (n) acessos em vez de n/2 operações (em média). Por exemplo, se uma lista tiver 10 7 = elementos (por exemplo, o número de portugueses na base de dados do BI), em vez de de acessos à lista (para encontrar um #BI), são necessários apenas cerca de log 2 (10 7 ) 23.25, em média. Evidentemente a ordenação tem custos. Mas, como é frequentemente o caso, a ordenação é feita 1 vez, e os acessos muitas vezes, compensa manter as estruturas de dados ordenadas.

14 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 14 Ordenação de Listas e Vectores Analisemos primeiro a ordenação de vectores (ou listas), para o que existem vários algoritmos (de ordenação) com vantagens e desvantagens em diferentes contextos. Uma característica importante dos algoritmos é o espaço de memória utilizado, que não consideraremos neste caso, já que apenas se utiliza o espaço ocupado pelo vector. Outra característica importante é a sua complexidade, medida em número de acessos ao vector. Este número depende naturalmente do número n de elementos da estrutura de dados utilizada. Embora existam algoritmos (quicksort) mais rápidos (necessitam de cerca de n log 2 n acessos), o que apresentamos (bubblesort) é mais simples de descrever (e implementar?).

15 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 15 Ordenação por Bubble Sort A ideia do algoritmo é comparar dois elementos consecutivos do vector, e trocá- los se tiverem na ordem errada. A comparação é feita entre os n-1 pares do vector, por uma determinada ordem, por exemplo (1,2), (2,3),..., (n-1,n). No final deste processo, o último elemento já está bem posicionado. Sem qualquer optimização, pode fazer-se outro varrimento, em que ficará bem colocado o penúltimo elemento. Desta forma, e no pior caso, bastará fazer n-1 varrimentos para garantir que o vector ficou ordenado. No total, e para o pior caso, são feitas (n-1) comparações em cada um dos (n-1) varrimentos, em que algumas comparações resultam em trocas. Desta forma serão feitas (n-1) 2 comparações, pelo que a complexidade será quadrática no número de elementos do vector, isto é lim (n-1) 2 n 2 (para valores de n grandes).

16 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 16 Ordenação por Bubble Sort Podemos observar o comportamento deste algoritmo no (pior) caso abaixo, com um vector de 4 elementos, em ordem decrescente que se pretende ordenar de forma crescente!

17 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 17 Bubble Sort (Não Optimizado) A função abaixo implementa o algoritmo de bubble sort com dois ciclos para encadeados. No final destes ciclos o vector está ordenado. function V = bubble_1(V); % bubble sort n = length(V); for k = 1:n-1 % n-1 varrimentos for i = 1:n-1 if V(i) > V(i+1) x=V(i); V(i)=V(i+1); %troca V(i) com V(i+1) V(i+1)=x; endif; endfor; endfunction;

18 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 18 Optimização do Bubble Sort O algoritmo pode ser optimizado de duas formas complementares. Diminuição dos ciclos Por um lado, em cada iteração o último valor a ser considerado vai decrescendo de n para n-1, para n-2,.... Desta forma o ciclo interno pode ser parametrizado por um valor k que vai decrescendo em cada ciclo externo. Interrupção dos varrimentos Se um varrimento termina sem trocas, o vector já está ordenado, e não é necessário fazer mais varrimentos. Assim há que identificar numa variável, troca, se houve trocas durante um varrimento. Caso contrário, terminar imediatamente a ordenação.

19 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 19 Bubble Sort (Optimizado) As duas optimizações descritas estão implementadas no algoritmo abaixo. Se ao fim de um varrimento não tiver havido trocas, o vector já está ordenado e a função termina sem iniciar mais varrimentos!. function V = bubble_2(V); % bubble sort n = length(V); for k = n-1:-1:1 % k = n-1, n-2, n-3,... troca = 0; for i = 1:k if V(i) > V(i+1) troca = 1; x=V(i); V(i)=V(i+1); %troca V(i) com V(i+1) V(i+1)=x; endif; endfor; if troca == 0 return endif; endfor; endfunction;

20 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 20 Bubble Sort (Optimizado) (versões Octave 3.0 e posteriores) Como a unica operação a fazer sobre vectores é trocar dois elementos, o mesmo algoritmo pode servir para ordenar vectores de estruturas. Por exemplo, a função abaixo ordena o vector Vec, por ordem crescente do campo venc. function Lista = bubble_3(Vec); % bubble sort n = length(Vec)-1; for k = n-1:-1:1 troca = FALSE; for i = 1:k if Vec(i).venc > Vec(i+1).venc troca = TRUE; x = Vec(i); %troca V(i) com V(i+1) Vec(i) = Vec(i+1); Vec(i+1) =x; endif; endfor; if !troca then return; endfor:; endfunction;

21 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 21 Bubble Sort (Optimizado) (versões Octave anteriores a 3.0) Como a unica operação a fazer sobre vectores é trocar dois elementos, o mesmo algoritmo pode servir para ordenar listas de estruturas. Por exemplo, a função abaixo ordena a lista por ordem crescente do campo venc. function Lista = bubble_3(Lista); % bubble sort n = length(Lista)-1; for k = n-1:-1:1 troca = FALSE; for i = 1:k if nth(lista,i).venc > nth(lista,i+1).venc troca = TRUE; x = nth(Lista,i); %troca V(i) com V(i+1) Lista(i)=nth(Lista,i+1); Lista(i+1)=x; endif; endfor; if !troca then return; endfor:; endfunction;

22 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 22 Pesquisa Linear em Vectores Consideremos um vector V, numérico e não ordenado, onde queremos encontrar o número x. O algoritmo abaixo determina se o número x está ou não incluído no vector, comparando x com todos os valores da lista. A função retorna o (primeiro) índice i onde se encontra x (ou seja, V(i) = x), ou retorna 0 se x não estiver incluído no vector A função pode ser facilmente adaptada para uma lista e um campo substituindo- se a comparação para if nth(Lista,i).campo == x function i = procura_linear_1(x,V); for i = 1:length(V); if V(i) == x return; endif endfor; i = 0; endfunction;

23 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 23 Pesquisa em Vectores A complexidade do algoritmo, em termos do número de acessos ao vector, pode ser analisado da seguinte forma: –Se x não pertence ao vector, então terão de ser feitas n leituras. –Se x pertencer ao vector, o número de leituras é variável. Assumindo que x pode estar em qualquer posição, deverão ser lidos, em média, n/2 valores. Assumindo que x pode estar em V com uma probabilidade p (e, portanto, não estar no vector com uma probabilidade q = 1-p), o número médio de acessos será de aproximadamente p n/2 + q n Se p = q = ½ teremos uma complexidade média de ½ ½ n + ½ n = ¾ n o que indica uma complexidade assintótica linear, O(n).

24 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 24 Pesquisa Linear em Vectores (Optimizada) A pesquisa pode ser mais rápida se o vector estiver ordenado. Assumindo uma ordenação crescente, a pesquisa pode terminar se o valor V(i) já exceder o valor de x, porque nesse caso, os valores de V(j) com j > i serão ainda maiores! function i = procura_linear_2(x,V); for i = 1:length(V); if V(i) == x return; elseif V(i) > x i = 0; return; endif endfor; endfunction;

25 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 25 Pesquisa Linear em Vectores (Optimizada) A complexidade, em termos do número de acessos ao vector, pode ser analisado de uma forma semelhante à anterior : –Se x pertencer ao vector V, o número de leituras é variável, sendo em média lidos n/2 valores. –Se x não pertencer ao vector V, esse facto será descoberto mais cedo ou mais tarde consoante o valor de x (e os valores em V). Em média, podemos assumir igualmente que apenas metade dos valores são testados Como x está em V com uma probabilidade p, e não está com probabilidade 1-p, o número médio de acessos será de p n/2 + (1-p) n/2 = n/2 O número de acessos baixa assim de ¾ n para ½ n, mas mantém a mesma complexidade assintótica linear, O(n).

26 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 26 Pesquisa Bipartida Se o vector V estiver ordenado, podemos sempre determinar se x, a existir no vector V, está à frente ou atrás de um elemento testado. Assim, em vez de testar sequencialmente os valores de V, podemos testá-los em saltos, delimitando em cada teste a zona do vector onde valerá a pena pesquisar. Esquemáticamente, podemos considerar um esquema de bipartição O algoritmo pode pois considerar um intervalo de pesquisa cada vez menor, como exemplificado de seguida. x > V(i) x < V(i) i

27 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 27 Pesquisa Bipartida Consideremos um vector V, ordenado por ordem crescente, com 31 números, onde queremos encontrar o número x. Inicialmente os índices onde se faz a pesquisa estão no intervalo (1,31). Podemos comparar x com o número intermédio entre 1 e 31 = 16 = (1+31)/2). –Se V(16) = x, este está encontrado. –Se V(16) < x, este deverá ser procurado no intervalo (17,31). –Se V(16) > x, este deverá ser procurado no intervalo (1,15). Neste último caso, podemos comparar x com o número intermédio 8 = (1+15)/2 –Se V(8) = x, este está encontrado. –Se V(8) < x, este deverá ser procurado no intervalo (9,15). –Se V(8) > x, este deverá ser procurado no intervalo (1,7).

28 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 28 Pesquisa Bipartida No segundo caso, podemos comparar x com o número intermédio 12 = 9+15/2. –Se V(12) = x, este está encontrado. –Se V(12) < x, este deverá ser procurado no intervalo (13,15). –Se V(12) > x, este deverá ser procurado no intervalo (9,11). No segundo caso, podemos comparar x com o número intermédio 14 = (13+15)/2. –Se V(14) = x, este está encontrado. –Se V(14) < x, este deverá ser procurado no intervalo (15,15). –Se V(14) > x, este deverá ser procurado no intervalo (13,13). Nestes últimos casos, são feitas comparações com um só elemento, V(13) ou V(15), que garantem a verificação sobre se x está ou não no vector V.

29 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 29 Pesquisa Bipartida No máximo, são feitas 5 comparações, com V(16), V(8), V(12), V(14) e V(15), o que confirma que o número máximo de acessos é da ordem de log 2 (n), já que log 2 (31) = Em geral, o intervalo inicial, de largura n, é reduzido para metade em cada um de p passos, sendo feita uma comparação em cada passo, e terminando o processo quando o intervalo tiver largura 1. Assim, temos n ½ ½... ½ = 1, donde n / 2 p = 1 e portanto n = 2 p ou p = log 2 (n). Como p é o número de comparações, a pesquisa bipartida tem, como visto atrás, complexidade assintótica logaritmica O( log 2 (n)). Assim para vectores (ou listas) com 10 9 valores, uma pesquisa requer em média log 2 (10 9 ) 29.9, e não 500*10 6 acessos. Se cada acesso demorar 1 s, a pesquisa bipartida demora cerac de 30 s, em comparação com 500 seg = 10 min!

30 21 Maio 2008 Vectores (e Listas): Pesquisa e Ordenação 30 Pesquisa Bipartida Dadas as vantagens, vale a pena utilizar a pesquisa bipartida. Eis uma possível implementação, recursiva, em que se pretende determinar se o número x está no vector V, entre as posições i e j. Naturalmente, a função será chamada como k = procura_bipartida(x,V,1,length(V)). function k = procura_bipartida(x,V,i,j); if i > j k = 0 % x não pertence a V else m = round((i+j)/2) if V(m) == x k = m; return; elseif V(m) < x i = m+1; % o j mantem-se else j = m-1; % o i mantem-se endif; k = procura_bipartida(x,V,i,j); endif endfunction;


Carregar ppt "Vectores (e Listas) : Pesquisa e Ordenação Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2007/2008 21 Maio 20081Vectores."

Apresentações semelhantes


Anúncios Google