termo Para resolver o problema, basta construir um Módulo (procedimento) para cada uma das definições: factor termo enquanto '+' ou '-'

Documentos relacionados
Capítulo V : Um Tipo Estruturado de Dados: o array

Análise e Desenvolvimento de Algoritmos (2006/2007)

Capítulo VII : A Recorrência

Capítulo V : A Linguagem Pascal Um Tipo Estruturado de Dados: o array 18. Para limite de n até 2 (* passagens de 1 até (n-1) *)

Métodos de Programação I Ana Maria de Almeida 92. Um objecto (uma função, um método) diz-se recorrente se é definido em termos de si próprio.

Pesquisa: operação elementar

Radix Sorting. Várias aplicações têm chaves que são inteiros, definidos dentro de um intervalo

Capítulo VI : Subprogramas

Métodos de Ordenamento e

Algoritmos de ordenação Ordenação rápida ( Quicksort )

1.2 OPERAÇÕES BÁSICAS EM ALGORITMOS E PROGRAMAS 18

Unidade VI. Técnicas de Teste de Software Teste Estrutural. Profa. Dra. Sandra Fabbri

Algoritmos de ordenação

Métodos de Programação I Ana Maria de Almeida

ALGORITMOS DE ORDENAÇÃO RECURSIVOS

Pascal. -Cabeçalho do programa. - label - const - type - var - procedure - function. - integer - real - byte - boolean - char - string

Departamento de Engenharia Rural Centro de Ciências Agrárias. Programação I

Procedimento. Função. Selecção Condicional - a instrução if-then-else. expressão if lógica then instrução else instrução

Algoritmos de pesquisa

Teoria da Computação e Algoritmos. Introdução à Linguagem Pascal. ALGORITMO <Nome do algoritmo>; <definições>; INÍCIO <Comandos>; FIM.

Modularidade. Objetivos: Introduzir noções básicas de modularidade. Funções e procedimentos

tipoveiculo = (bicicleta, motociclo, motorizada, automovel, autocomreb, camioneta, autocarro, camiao, reboque); veiculo : tipoveiculo;

Tipos de Dados Dinâmicos

Sintaxe do Pascal Simplificado Estendido de 12 novas construções em Notação EBNF (BNF estendida)

Lista 13. Program Pzim ; var dez : array [ ] of real; i:integer; Begin //lê 10 valores for i:= 1 to 10 do readln(dez[i]); //calcula

Aulas Anteriores. Detalhes da linguagem de programação

Linguagem de programação: Pascal

Linguagem Pascal. Prof. Antonio Almeida de Barros Junior

Estrutura de Dados Polinómio

Refinamentos sucessivos

UNIVERSIDADE DE SÃO PAULO ICMC SCC 202 Algoritmos e Estrutura de Dados I - 2º Semestre 2010 Profa. Sandra Maria Aluísio;

Exercícios sobre o Capítulo III

Conjunto (set) O tipo estruturado set representa, em Pascal, um conjunto de objectos de um dado tipo;

ESTRUTURA DE DADOS E ALGORITMOS. Árvores Binárias de Busca. Cristina Boeres

6) ESTRUTURA DE UM PROGRAMA

2.2.5 EXPRESSÕES - Regras para o cálculo de valores

Árvores Binárias de Pesquisa (ABP) INF01203 Estruturas de Dados. Operações. Árvores Binárias de Pesquisa (ABP) Caminhamento Central à Esquerda

8. ÁRVORES ÁRVORES Niv 1 Niv 2 Niv 3 Niv 4. Até Introdução

Ordenação: QuickSort. Prof. Túlio Toffolo BCC202 Aula 15 Algoritmos e Estruturas de Dados I

Algoritmia e Programação

Árvores Binária de Busca. Prof. César Melo DCC/ICE/UFAM

Quicksort. David Menotti Algoritmos e Estruturas de Dados II DInf UFPR

Árvore Binária de Busca. Prof. César Melo

Arquivos Sequenciais. Estruturas de Dados II Vanessa Braganholo

Introdução à Programação 2006/07. Algoritmos

Capítulo IV : A Linguagem Pascal Ficheiros de Texto

Pesquisa e Ordenação

Linguagem e Técnicas em Programação. Gilson de Souza Carvalho

Programando o Computador com PascaL: um ambiente para Auto-Aprendizagem.

Ciclo com Contador : instrução for. for de variável := expressão to. expressão do instrução

= = = = = = = = = = = = = = = =

O AMBIENTE DE PROGRAMAÇÃO VISUAL -PLANO DE ENSINO. Prof. Angelo Augusto Frozza, M.Sc.

Teste de P1 12 de Dezembro 2001

Sumário. Ciência da Computação. Prof. Dr. Leandro Alves Neves. Aula 10. Algoritmos e Programação. Enquanto (Teste no início) Repeat (Teste no final)

Linguagem Pascal. Definição e Tipos de Dados. Professora Lara Popov Zambiasi Bazzi Oberderder. Linguagem PASCAL 1

Programação Introdução

Aula Anterior. Decomposição algorítmica (continuação)

Classificação por Seleção - selection sort

Introdução à Ciência da Computação

Ponteiros em Pascal. Variáveis ponteiros são aquelas que. Declaração em Pascal: var ptint: ^integer; {ponteiro para uma variável inteira } real} 1

Árvores & Árvores Binárias

Capítulo 14. Ordenação e pesquisa. Bubblesort. Alguns algoritmos de ordenação e pesquisa Medição do tempo de execução de um programa

Busca. Prof. Alneu de Andrade Lopes. ICMC - USP - São Carlos

Folha 4.2 Análise sintática ascendente

Métodos de Programação I Ana Maria de Almeida

INTRODUÇÃO À LINGUAGEM PASCAL PREFÁCIO

Complexidade de Algoritmos

Resumo 2 - Mapeamento Portugol-Pascal

Análise Semântica e Tratamento de Erros Dependentes de Contexto

IFTO TÉCNICO EM INFORMÁTICA DESENVOLVIMENTO DE SISTEMAS AULA 01

Algoritmos e Estruturas de Dados. Décima sexta aula: Quicksort

Linguagem Pascal. Prof. Jonatas Bastos Site:

APÊNDICE A - FUNDAMENTOS DA LINGUAGEM DE PROGRAMAÇÃO PASCAL.

ÁRVORES BINÁRIAS DE BUSCA. Vanessa Braganholo Estruturas de Dados e Seus Algoritmos

Linguagens de Programação

ÁRVORE BINÁRIA DE BUSCA

3. 1. Teste no Início do Ciclo (Repetição enquanto ):

Estrutura de Dados. Algoritmos de Ordenação. Prof. Othon M. N. Batista Mestre em Informática

Ordenação. Última alteração: 26 de Março de Transparências elaboradas por Fabiano C. Botelho e Nivio Ziviani

ENGENHARIA DE PRODUÇÃO ICC 1 TÉCNICAS DE PROGRAMAÇÃO

DELPHI Curso Extensão. walter Prof. Walter Gima

Métodos de Programação I (2005/2006) 1. Ficheiro (file)

Aula Anterior. Noção de array (continuação) Introdução aos subprogramas. Exemplos de aplicação

Compiladores Prof. a Mariella Berger. Trabalho 2 Analisador Léxico

Classificação por Inserção - insertion sort

ALGORITMOS DE ORDENAÇÃO

UNISINOS - UNIVERSIDADE DO VALE DO RIO DOS SINOS CENTRO DE CIÊNCIAS EXATAS E TECNOLÓGICAS (C6/6) Curso: Informática

Ordenação. Ordenação. Introdução - Conceitos Básicos. Introdução - Conceitos Básicos

SCC 202 Algoritmos e Estruturas de Dados I. Pilhas (Stacks) (implementação dinâmica)

Vectores: Algoritmos de Ordenação. Algoritmos e Estruturas de Dados 2009/2010

AED2 - Aula 11 Problema da separação e quicksort

Introdução à Computação II Unesp Rio Claro 2012Prof. Rafael Oliveira

ORDENAÇÃO E BUSCA 1. MÉTODOS DE ORDENAÇÃO

Algoritmos de pesquisa

ALGORITMOS E ESTRUTURAS DE DADOS CES-11 Prof. Paulo André Castro Sala 110 Prédio da Computação IECE - ITA

Estruturas de Dados 2

Ordenação. Insertion Sort

Algoritmos e Estruturas de Dados II. Ordenação

Transcrição:

Capítulo VII : A Recorrência 17 _ Para resolver o problema, basta construir um Módulo (procedimento) para cada uma das definições: expressão termo termo enquanto '+' ou '-' termo escrever operador factor enquanto '*' ou '/' factor escrever operador factor identificador escrevê-lo '(' expressão Exemplo: a * (b + c) a b c + * expressão: termo: factor: escrever(a) factor: expressão: escrever(*) termo: factor: escrever(b) termo: factor: escrever(c) escrever(+)

Capítulo VII : A Recorrência 18 _ Programa Pascal: program InfixPostfix(input, output); var car : char; procedure procurar; begin repeat read(car); until (car <> ' ') or eoln(input) (* procurar *); procedure expressao; var operaditivo : char; procedure termo; var opermult : char; procedure factor; begin (* factor *) if car = '(' then begin procurar; expressao else write(car); procurar (* factor *); begin (* termo *) factor; while (car = '*') or (car = '/') do begin opermult:= car; procurar; factor; write(opermult) (* termo *);

Capítulo VII : A Recorrência 19 _ begin (* expressao *) termo; while (car = '+') or (car = '-') do begin operaditivo:= car; procurar; termo; write(operaditivo) (* expressao *); begin (* Programa Principal *) procurar; repeat expressao; writeln until car = '.' (*InfixPostfix *). Alguns resultados: input output (a+b)*(c -d) a+b*c-d ( a +b)* c-d a+b*(c-d) a *a *a*a b+c *(d+c*a*a) *b + a ( a* b ) / c a*b/c a*( b/c) a*a/a*a/a*a. ab+cd-* abc*+dab+c*dabcd-*+ aa*a*a* bcdca*a*+*b*+a+ ab*c/ ab*c/ abc/* aa*a/a*a/a* Problemas: Calcular o valor de uma expressão postfix. Conversão postfix infix.

Capítulo VII : A Recorrência 20 _ Os Métodos de Pesquisa também admitem Abordagens Recorrentes... Ex13: Pesquisa Linear num Vector (não ordenado): Versão Iterativa de um Módulo Completo de Pesquisa: procedure pesquisar (x : vector; n : integer; este : elemento; var achou : boolean; var : indice : integer); var i : integer; begin i:= 1; while (x[i] <> este) and (i<n) do i:= i +1; (* Aqui (x[i] = este) or (i>=n) *) achou:= x[i] = este; if achou then indice:= i else indice:= 0 ; Uma Estratégia Recorrente: Contudo, procurar em x[1..n]: se este = x[n] então achou senão procurar em x[1..n-1] É necessário garantir que o processo pára mesmo que o elemento não seja encontrado, isto é, falta identificar o Caso Trivial da Recorrência. Não convem que o procedimento Recorrente contenha a lista completa dos Parâmetros pois, por exemplo (x : vector) iria gerar uma cópia de todo o vector para cada Chamada Recorrente. Uma solução consiste no Encapsulamento da Recorrência, isto é, na utilização de um procedimento Recorrente interno ao Módulo de Pesquisa pretido.

Capítulo VII : A Recorrência 21 _ Módulo de Pesquisa com Recorrência Encapsulada: procedure pesquisar (x : vector; n : integer; este : elemento; var achou : boolean; var : indice : integer); procedure pesq(n : integer); begin if n>=1 then begin if este = x[n] then indice := n else pesq(n-1) else indice:= 0 (* pesq *); begin pesq(n); achou:= indice<>0 (* pesquisar *); O subprograma Recorrente pode também ser uma Função: procedure pesquisar (x : vector; n : integer; este : elemento; var achou : boolean; var : indice : integer); function pesq(n : integer) : integer; begin if n>=1 then begin if este = x[n] then pesq:= n else pesq:= pesq(n-1) else pesq:= 0 (* pesq *); begin indice:= pesq(n); achou:= indice<>0 (* pesquisar *);

Capítulo VII : A Recorrência 22 _ Ex14: Pesquisa num Vector ordenado: Módulo de Pesquisa Binária com Recorrência Encapsulada: procedure pesquisar (x : vector; n : integer; este : elemento; var achou : boolean; var : indice : integer); function pesq(esq, dir : integer) : integer; var meio : integer; begin if esq <= dir then begin meio:= (esq+dir) div 2; if este = x[meio] then pesq := meio else if este < x[meio] then pesq:= pesq(esq, meio-1) else pesq:= pesq(meio+1, dir) else pesq:= 0 (* pesq *); begin indice:= pesq(1, n); achou:= indice<>0 (* pesquisar *); Exercício: Identificar o maior elemento de um vector, utilizando a seguinte Estratégia Recorrente: procurar máximo (de todo o vector): procurar máximo (da primeira metade); procurar máximo (da segunda metade); escolher o maior.

Capítulo VII : A Recorrência 23 _ E também os Métodos de Ordenamento... Ex15: Ordenamento por Inserção (Ver Cap. V, pág. 22): Uma Estratégia Recorrente: ordenar x[1..n]: ordenar x[1..n-1]; inserir x[n] em x[1..n-1]. Módulo Recorrente de Ordenamento por Inserção: procedure OrdInsercao (var x : vector; n : integer); procedure inserir(novo : elemento; k : integer); (* Ver Cap. V, pág. 15 *) var i : integer; begin if novo >= x[k] then x[k+1]:= novo else begin i:= k; while (i>=1) and (x[i]>novo) do begin x[i+1]:= x[i]; i:= i-1 ; x[i+1]:= novo ; (* inserir *); begin if n>1 then begin OrdInsercao(x, n-1); inserir(x[n], n-1) (* OrdInsercao *);

Capítulo VII : A Recorrência 24 _ A Abordagem Recorrente permite a construção de Métodos de Ordenamento muito eficientes... Ex16: Ordenamento por Fusão: Observações: O Problema da Fusão de dois Vectores, já ordenados, é menos complexo do que o Problema do Ordenamento; A Recorrência permite transformar (reduzir) o processo do Ordenamento num processo de Fusão Ordenada. Estratégia Recorrente: Ex.: ordenar vector: ordenar a primeira metade; ordenar a segunda metade; fundir as duas metades. Maria João Paulo Ana Rosa Rui Pedro Maria João Paulo Ana Rosa Rui Pedro Maria João Paulo Ana Rosa Rui Pedro Maria João Paulo Ana Rosa Rui João Maria Ana Paulo Rosa Rui Ana João Maria Paulo Pedro Rosa Rui Ana João Maria Paulo Pedro Rosa Rui Basta portanto construir um módulo para a Fusão de dois SubVectores já ordenados.

Capítulo VII : A Recorrência 25 _ Problema: Ordenar o vector x[a..d], sabo que os subvectores x[a..b] e x[c..d], com b+1=c, estão já ordenados. Procedimento Pascal: procedure fundir (a, b, c, d : integer); var i, j, k : integer; aux : elemento; begin i:= a; j:= c; repeat (* Inserir x[j] *) if x[i] > x[j] then begin aux := x[j]; for k:= j downto (i+1) do x[k]:= x[k-1]; x[i]:= aux; j:= j+1 else i:= i+1 until (i>=j) or (j>d) (* fundir *);

Capítulo VII : A Recorrência 26 _ Módulo Recorrente de Ordenamento por Fusão: procedure OrdFusao (var x : vector; n, m : integer); var meio : integer; procedure fundir (a, b, c, d : integer); var i, j, k : integer; aux : elemento; begin i:= a; j:= c; repeat (* Inserir x[j] *) if x[i] > x[j] then begin aux := x[j]; for k:= j downto (i+1) do x[k]:= x[k-1]; x[i]:= aux; j:= j+1 else i:= i+1 until (i>=j) or (j>d) (* fundir *); begin if m-n >= 1 then begin meio:=(n+m) div 2; OrdFusao(x, n, meio); OrdFusao(x, meio+1, m); fundir(n, meio, meio+1, m) (* OrdFusao *);

Capítulo VII : A Recorrência 27 _ A Recorrência está na origem daquele que é habitualmente considerado o mais rápido dos Métodos de Ordenamento... Ex17: QuickSort (C. A. R. Hoare, 1961): Observações: Ao Ordenar um Vector, as Trocas mais produtivas são as efectuadas entre elementos mais afastados; Se o Vector inicial estiver por ordem inversa da pretida, um bom Método de Ordenamento deverá realizar apenas n div 2 trocas. (Ver Cap.V, pág.7) A ideia fundamental do QuickSort, consiste em: Separar os elementos do vector dado, de modo que todos os pequenos fiquem na parte esquerda e todos os grandes na parte direita. O Processo da Separação é então aplicado a cada uma das partes... Estratégia Recorrente: ordenar vector: Separar em pequenos e grandes; ordenar os pequenos; ordenar os grandes.

Capítulo VII : A Recorrência 28 _ Resta assim estabelecer uma definição adequada para elementos pequenos e grandes, bem como construir um Algoritmo para a Separação. Problema: Dado um vector x[1..n] e um elemento arbitrário A, Separar os elementos de x, de modo que os inferiores fiquem à esquerda e os superiores à direita de A. A A Algoritmo para a Separação do vector x[esq..dir]: i esq (* Começa na esquerda e avança *) j dir (* Começa na direita e recua *) Procurar o menor i, tal que x[i] A Procurar o maior j, tal que x[j] A se i j trocar x[i] com x[j] avançar i e recuar j Até que i>j

Capítulo VII : A Recorrência 29 _ Algoritmo de Separação de Hoare, em Pascal, dados um vector x[esq..dir] e um elemento arbitrário A x[esq..dir]: (* Inicializar i e j *) i:= esq; j:= dir; repeat (* Procurar o menor i, tal que x[i] A *) while x[i]<a do i:= i+1; (* Aqui x[i] A *) (* Procurar o maior j, tal que x[j] A *) while x[j]>a do j:= j-1; (* Aqui x[j] A *) if i<= j then begin (* Trocar x[i] com x[j] *) aux := x[i]; x[i]:= x[j]; x[j]:= aux; (* Avançar i e recuar j *) i:= i+1; j:= j-1 until i>j; (* Aqui x[esq..i-1] A and x[j+1..dir] A *)

Capítulo VII : A Recorrência 30 _ Módulo Recorrente para o QuickSort: procedure QuickSort (var x : vector; n : integer); procedure Sort (esq, dir : integer); var i, j : integer; A, aux : elemento; begin (* Fase da Separação *) i:= esq; j:= dir; (* O elemento Arbitrário pode ser o do meio *) A:= x[(esq+dir) div 2]; repeat while x[i]<a do i:= i+1; (* Aqui x[i] A *) while x[j]>a do j:= j-1; (* Aqui x[j] A *) if i<= j then begin (* Trocar x[i] com x[j] *) aux :=x[i]; x[i]:=x[j]; x[j]:=aux; (* Avançar i e recuar j *) i:= i+1; j:= j-1 until i>j; (* Aqui x[esq..i-1] A and x[j+1..dir] A *) (* Chamadas Recorrentes *) if esq < j then Sort(esq, j); if i < dir then Sort(i, dir) (* Sort *); begin Sort(1, n) (*QuickSort *);

Capítulo VII : A Recorrência 31 _ Simulação: Sort(1, 9): esq = 1; dir = 9; A = 46; Separação: Sort(1, 5): esq = 1; dir = 5; A = 12; Sort(6, 9): esq = 6; dir = 9; A = 46; Separação: Separação: Sort(1, 2): esq = 1; dir = 2; A = 6; Sort(3, 5): esq = 3; dir = 5; A = 42; Sort(7, 9): esq = 7; dir = 9; A = 55; Separação: Separação: Separação: Sort(8, 9): esq = 8; dir = 9; A = 94; Separação:

Capítulo VII : A Recorrência 32 _ Uma Análise da Complexidade Teórica, demonstra que o QuickSort é efectivamente o mais eficiente dos Métodos de Ordenamento; Um Estudo Estatístico mostra que essa propriedade se manifesta, muito em particular em vectores de grandes dimensões, bem como nos casos mais difíceis ; Por outro lado nos casos fáceis, como no caso do vector dado já se encontrar (ou quase) ordenado, o QuickSort realiza operações inúteis (troca de elementos por si próprios); Para vectores pequenos e/ou quase ordenado, os métodos mais simples são os mais convenientes; Consideremos o seguinte melhoramento do QuickSort, destinado a evitar o caso da troca de um elemento por si próprio: if i<= j then begin if i <> j then begin (* Trocar x[i] com x[j] *) aux := x[i]; x[i]:= x[j]; x[j]:= aux; ; (* Avançar i e recuar j *) i:= i+1; j:= j-1 Note-se contudo que, para evitar alguns (raros) casos de trocas inúteis, foi necessário introduzir uma nova comparação. Com esta alteração, o QuickSort realiza efectivamente n div 2 trocas, no caso do vector dado se encontrar por ordem inversa. Verifique.

Capítulo VII : A Recorrência 33 _ O algoritmo da Separação de Hoare, só por si, pode ainda fornecer uma solução simples para outros tipos de problemas. Por exemplo: Dado um vector de elementos inteiros e positivos, separar os números pares dos ímpares, indicando quantos existem de cada. Procedimento Pascal: procedure SepararParesImpares (var x : vector; n : integer); var i, j : integer; aux : integer; begin i:= 1; j:= n; repeat while odd(x[i]) do i:= i+1; (* x[1..i-1] impares and x[i] par *) while not odd(x[j]) do j:= j-1; (* x[j] impar and x[j+1..n] pares *) if i<=j then begin aux :=x[i]; x[i]:=x[j]; x[j]:=aux; i:= i+1; j:= j-1 until i>j; (* x[1..i-1] impares and x[j+1..n] pares *) writeln('existem ', i-1, ' números ímpares e ', n-j, ' pares.') (* SepararParesImpares *); Ex.: Existem 5 números ímpares e 7 pares.