CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas – 2016

Slides:



Advertisements
Apresentações semelhantes
Listas encadeadas Prof. Rosana Palazon.
Advertisements

Programação II Estruturas de Dados
David Menotti Algoritmos e Estruturas de Dados I DECOM – UFOP
Denise Guliato Faculdade de Computação – UFU
Denise Guliato Faculdade de Computação – UFU
Educação Profissional Técnica de Nível Médio Curso Técnico de Informática
CES-10 INTRODUÇÃO À COMPUTAÇÃO Aulas Práticas – 2014 Capítulo X Encadeamento de Estruturas por Ponteiros.
Fundamentos de Programação 1 Slides 18 Prof. SIMÃO Jean Marcelo SIMÃO Linguagem C “Arquivos Seqüências ou de Texto ”. 1.
Disciplina:PROA3V José Henrique Verhalem e Renan Tenório Professor: Alexandre Cassimiro Novembro 2015.
Linguagem de Programação – Aula 03 Prof. Me. Ronnison Reges Vidal.
Princípios de Desenvolvimento de Algoritmos MAC122 Prof. Dr. Paulo Miranda IME-USP Variáveis e Atribuições.
Introdução à Computação para Engenharia MAC2166
Tópicos Preliminares Algorítmos I.
Estruturas de Dados Aula 2: Estruturas Estáticas
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas – 2017
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS
Introdução à Programação
Algoritmos e Estruturas de Dados I
Programação em C Aula 8.
Construção de Algoritmos AULA 04
Capítulo II – Listas Lineares Gerais
Fundamentos de Programação 1
Comandos da Linguagem C
Estruturas de Repetição
Linguagem C Para programadores Python
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas
INF1007 – Programação 2 9 – Pilhas
CES-11 ESTRUTURAS DE DADOS Aulas Práticas
Módulo I Capítulo 3: Fluxo de Código e Operador Condicional
Capítulo VIII – Técnicas de Ordenação
Capítulo 8 - Caracteres e Strings
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas
Prof. Wellington Franco
Estrutura de dados Pilhas e filas
FUNDAMENTO DE PROGRAMAÇÃO PROF. BRUNO DE CASTRO H. SILVA
Capítulo IV – Árvores Gerais
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas – 2017
Prof. Wellington Franco Manipulação de Arquivos em C
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas
Capítulo IV – Árvores Gerais
FUNDAMENTO DE PROGRAMAÇÃO
UNIDADE 7 Tipos estruturados
PROGRAMAÇÃO I UNIDADE 3.
INE 5201 – INTRODUÇÃO À CIÊNCIA DA COMPUTAÇÃO
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS
Algoritmos e Programação MC102
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas
Listas Encadeadas.
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas – 2017
Fundamentos de Programação 1
Complexidade de Algoritmos
Profa. Maria Augusta Constante Puget
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS
EDA - Prof. Paulemir Campos
Estruturas de Dados aula 3
Prof. Rafael Mesquita Pilha Prof. Rafael Mesquita
Fundamentos de Programação 1
DHD – Desenvolvimento em Hardware
Filas.
Arrays de caracteres: strings
ALGORITMOS.
Linguagem C Linguagem Imperativa
Prof. Rafael Mesquita Listas Encadeadas Prof. Rafael Mesquita
Python: Comandos Básicos
Introdução a progrmação Comandos condicionais: if e switch
Cálculo Numérico Aula 3 – Arredondamento e Operações /04/2014
RESULUÇÃO DOS EXERCÍCIOS E
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas – 2019
Aula 7 Professores: Conteúdo: Dante Corbucci Filho
Aula 3 Professores: Conteúdo: Dante Corbucci Filho
Transcrição da apresentação:

CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas – 2016 Capítulo III Pilhas

Ler uma expressão na forma parentética; por exemplo, a expressão: Objetivos do Lab 3: Ler uma expressão na forma parentética; por exemplo, a expressão: tem a seguinte forma parentética: Transformar, usando uma pilha, a parentética numa polonesa equivalente: Calcular, usando uma pilha, o valor da polonesa ^

(((x1 + x2) * (x3 + (x4 * x5))) + x6) Exercício 3.1: Obtenção dos átomos de uma expressão aritmética parentética Sejam expressões do tipo: (((x1 + x2) * (x3 + (x4 * x5))) + x6) também chamadas expressões na forma parentética onde xi é um número inteiro não negativo com um ou mais dígitos decimais, onde os operadores são somente “+” e “*”, e onde todas as operações são colocadas entre parênteses Átomos de uma expressão como essas são os seus números, seus operadores e seus parêntesis

Um átomo é uma entidade contendo dois campos: o tipo e um eventual atributo Um átomo pode ser de um dos seguintes tipos: NUM (abrev. de número): quando ele for um número inteiro OPER (abrev. de operador): quando ele for um dos caracteres ‘+’ ou ‘*’ ABPAR (abrev. de abre-parêntesis): quando ele for o caractere ‘(’ FPAR (abrev. de fecha-parêntesis): quando ele for o caractere ‘)’ INVAL (abrev. de átomo inválido): quando ele for qualquer outro caractere

O eventual atributo de um átomo depende de seu tipo: NUM: o atributo é o valor numérico do número OPER: o atributo é o próprio caractere ‘+’ ou ‘*’ ABPAR: o átomo não precisa de atributo FPAR: o átomo também não precisa de atributo INVAL: o atributo é o próprio caractere Tarefa: completar o esqueleto de programa a seguir que: Lê uma expressão na forma parentética Encontra seus átomos (tipos e atributos), guardando-os numa lista de átomos (vetor de átomos) Escreve no vídeo o conteúdo dessa lista

Exemplo: os átomos da expressão (13 * (45 + 7) &) (13 * (45 + 7) &) serão guardados na seguinte lista de átomos denominada Parentetica: O campo para o atributo de um átomo deverá ser uma union A seguir, o esqueleto de programa ABPAR NUM 13 OPER * 45 + 7 FPAR INVAL & Vetor natom 10 Parentetica 1 2 3 4 5 6 8 9

/* Inclusao de bibliotecas de C */ #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <ctype.h> /* Declaracoes para o tipo logic */ typedef char logic; const logic TRUE = 1, FALSE = 0; /* Definicao dos tipos de atomos */ #define NUM 1 #define OPER 2 #define ABPAR 3 #define FPAR 4 #define INVAL 5 A serem usadas nos próximos exercícios

/* Declaracoes de tipos para as expressoes e listas de atomos */ typedef char expressao[50]; typedef union atribatomo atribatomo; union atribatomo { int valor; char carac; }; typedef struct atomo atomo; struct atomo { int tipo; atribatomo atrib; typedef struct listaatomos listaatomos; struct listaatomos { int natom; atomo Vetor[50]; Campo valor: Para átomos do tipo NUM Campo carac: Para átomos de tipos OPER e INVAL tipo atrib O tipo atomo

/* Variaveis globais */ int i; char c; expressao Expr; listaatomos Parentetica; /* Prototipos das funcoes auxiliares */ void ArmazenarParentetica (void); void EscreverListaAtomos (listaatomos *); char ProxNaoBranco (void); char ProxCarac (void); void InicExpr (void); ArmazenarParentetica: armazena os átomos de Expr na variável global Parentetica EscreverListaAtomos: escreve todos os átomos de uma lista de átomos Haverá mais uma lista além da Parentetica O argumento é passado por referência Podem ser escritas outras funções caso sejam convenientes

/* Funcao main */ int main() { char c; printf ("Armazenar expressao parentetica? (s/n): "); do c = getche (); while (c!='s' && c!='n' && c!='S' && c!='N'); while (c == 's' || c == 'S') { printf ("\n\n"); printf ("Digite a expressao: "); setbuf (stdin, NULL); gets (Expr); ArmazenarParentetica (); EscreverListaAtomos (&Parentetica); printf ("\n\nArmazenar expressao parentetica? (s/n): "); } printf ("\n\n"); printf ("Fim das atividades!"); printf ("\n\n"); system ("pause"); return 0;

Diretrizes para a função ArmazenarParentetica void ArmazenarParentetica () { Zerar o número de átomos de Parentetica; Posicionar o cursor de Expr em seu início; Capturar o primeiro caractere não-branco; Enquanto ele não for o ‘\0’ { Preparar para formar um novo átomo; Se o caractere for um dígito { Coletar os outros dígitos; O tipo do átomo é NUM; O atributo é o valor numérico da cadeia formada pelos dígitos coletados; } Se for '+' ou '*' { O tipo do átomo é OPER; O atributo é o próprio caractere; Diretrizes para a função ArmazenarParentetica

Diretrizes para a função ArmazenarParentetica Se for '(' ou ')' { O tipo do átomo é ABPAR ou FPAR; O atributo não é necessário; } Se for qualquer outro caractere { O tipo do átomo é INVAL; O atributo é o próprio caractere; Armazenar o átomo no final de Parentetica; Acrescentar uma unidade ao número de átomos de Parentetica; Capturar o próximo caractere não-branco; } /* Fim do Enquanto */ } /* Fim da função ArmazenarParentetica */ Cuidado com os comandos para percorrer Expr Diretrizes para a função ArmazenarParentetica

Diretrizes para a função EscreverListaAtomos: TIPO | ATRIBUTO -------------------- ABPAR | NUM | 12 OPER | + NUM | 32 FPAR | OPER | * NUM | 13 INVAL | & NUM | 43 INVAL | ; Para uma expressão tal como ((12+32)*13 & + 43;)) a função deverá mostrar no vídeo uma tabela semelhante à seguinte:

/* Funcoes para percorrer a expressao */ char ProxNaoBranco () { while (isspace (Expr[i]) || (iscntrl (Expr[i]) && Expr[i] != '\0')) i++; return Expr[i]; } char ProxCarac () { i++; void InicExpr () { i = 0;

Exercício 3.2: Verificar se uma sequência de átomos é uma forma parentética correta A forma parentética de uma expressão pode ser definida recursivamente da seguinte maneira: Sendo m e n dois números inteiros não negativos com um ou mais dígitos cada, (m + n) e (m * n) são expressões na forma parentética Sendo α e β números inteiros não negativos ou expressões na forma parentética, (α + β) e (α * β) também são expressões na forma parentética É necessário adaptar essa definição a expressões compostas de átomos, conforme definido no exercício anterior

Seja forma parentética definida para expressões em que os números são formados por apenas um dígito A forma parentética de uma expressão pode ser definida recursivamente da seguinte maneira: Sendo m e n dois dígitos quaisquer, (m + n) e (m * n) são expressões na forma parentética Sendo α e β dígitos ou expressões na forma parentética, (α + β) e (α * β) também são expressões na forma parentética Neste caso, a programação para checar se a expressão é uma forma parentética pode ser composta pelas seguintes funções:

/* Funcao ParenteticaCorreta */ logic ParenteticaCorreta () { logic r; i = 0; r = TesteRecursivo(); if (Expr[i] != '\0') r = FALSE; return r; }

/* Funcao TesteRecursivo */ logic TesteRecursivo () { logic r = TRUE; if (Expr[i] == '(') { i++; if (isdigit (Expr[i])) i++; else if (Expr[i] == '(') r = TesteRecursivo (); else r = FALSE; if (r && (Expr[i] == '+' || Expr[i] == '*')) i++; if (r && isdigit (Expr[i])) i++; else if (r && Expr[i] == '(') if (r && Expr[i] == ')') i++; } return r; Estas funções podem servir de guias para expressões compostas de átomos e para átomos numéricos contendo mais de um dígito

(((x1 + x2) * (x3 + (x4 * x5))) + x6) Exercício 3.3: Formar a polonesa correspondente à parentética armazenada Conforme exercício resolvido em aula teórica, a parentética (((x1 + x2) * (x3 + (x4 * x5))) + x6) pode ser colocada na forma polonesa sufixa, ou simplesmente polonesa, caracterizada pela transformação: x1 x2 + x3 x4 x5 * + * x6 + Obter uma lista de átomos correspondente à polonesa de uma expressão guardada numa lista de átomos, na forma parentética

Método de transformação: Percorrer o vetor da parentética Ao encontrar um número, inseri-lo no final da polonesa Ao encontrar um operador, colocá-lo numa pilha de átomos Ao encontrar um abre-parêntesis, nada fazer Ao encontrar um fecha-parêntesis, desempilhar um operador e colocá-lo no final da polonesa Sugestão: montar a polonesa durante o teste da parentética

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) Parentética Polonesa Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) Parentética Polonesa Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) Parentética Polonesa Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) Parentética Polonesa Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 Parentética Polonesa 23 Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 Parentética Polonesa 23 + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 Parentética Polonesa 23 + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 Parentética Polonesa 23 90 + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 Parentética Polonesa 23 90 + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + Parentética Polonesa 23 90 + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + Parentética Polonesa 23 90 + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + Parentética Polonesa 23 90 + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + Parentética Polonesa 23 90 + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 Parentética Polonesa 23 90 + 8 * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 Parentética Polonesa 23 90 + 8 + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 Parentética Polonesa 23 90 + 8 + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 Parentética Polonesa 23 90 + 8 + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 * Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 * Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 * + Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 * + Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 * + * Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 * + * Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) 23 90 + 8 53 12 * + * Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * 42 + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * 42 + Pilha de operadores

Simulação: (((23 + 90) * (8 + (53 * 12))) + 42) Parentética (((23 + 90) * (8 + (53 * 12))) + 42) Polonesa 23 90 + 8 53 12 * + * 42 + Polonesa formada ! Pilha de operadores

Declarações e protótipos para o TAD Pilha (estrutura encadeada): typedef struct noh noh; typedef noh *pilha; struct noh {atomo elem; noh *prox;}; void Empilhar (atomo, pilha*); void Desempilhar (pilha*); atomo Topo (pilha); void InicPilha (pilha*); logic Vazia (pilha); Os elementos da pilha são átomos

Funções-operadoras para o TAD Pilha (encadeada): void Empilhar (atomo x, pilha *P) { noh *temp; temp = *P; *P = (noh *) malloc (sizeof (noh)); (*P)->elem = x; (*P)->prox = temp;} void Desempilhar (pilha *P) { noh *temp; if (! Vazia(*P)) {temp = *P; *P = (*P)->prox; free (temp); } } atomo Topo (pilha P) {if (! Vazia(P)) return P->elem;} void InicPilha (pilha *P) { *P = NULL; } logic Vazia (pilha P) { if (P == NULL) return TRUE; else return FALSE; }

Exercício 3.4: Cálculo de expressões em polonesa Foi visto que, para se calcular o valor de uma expressão em polonesa, pode-se utilizar uma pilha: Percorre-se o vetor da polonesa Ao encontrar um número, deve-se colocá-lo na pilha Ao encontrar um operador, desempilha-se dois números, realiza-se a operação e empilha-se o resultado Não é necessário testar a polonesa, uma vez que ela é construída a partir de uma parentética correta Quando a expressão de entrada estiver incorreta, sua parentética armazenada será rejeitada

Exercício 3.5: Extensão para operandos reais Estender o programa do Exercício 3.4 para trabalhar com números reais Aceitar como número uma string que comece com um ou mais dígitos, seguidos opcionalmente por um ponto e zero ou mais dígitos Exemplos: 127 56. 98.75 0.002 Exercício 3.6: Extensão do programa do Exercício 3.5 para os operadores binários de subtração ‘-’ e divisão ‘/’

~: menos unário ^: potenciação L: logaritmo R: raiz quadrada Exercício 3.7: Estender o programa do Exercício 3.6 para trabalhar com os seguintes operadores: ~: menos unário ^: potenciação L: logaritmo R: raiz quadrada Exemplos de expressões parentéticas e polonesas usando esses operadores: