• Nenhum resultado encontrado

Exame de Programação Estruturada (A)

N/A
N/A
Protected

Academic year: 2021

Share "Exame de Programação Estruturada (A)"

Copied!
6
0
0

Texto

(1)

Exame de Programa¸

ao Estruturada (A) — 2006.06.16

UMA RESOLUC

¸ ˜

AO (VERS ˜

AO A)

1.

Resposta:

static int indicevogal(int c) { switch(c) {

case ’A’:

case ’a’: return 0; case ’E’:

case ’e’: return 1; case ’I’:

case ’i’: return 2; case ’O’:

case ’o’: return 3; case ’U’:

case ’u’: return 4; default: return -1; }

}

void frequencia(char *nomefin) { int c, n, i;

struct { char vog; int num; } freqabs[5] =

{{’A’,0}, {’E’,0}, {’I’,0}, {’O’,0}, {’U’,0}}; FILE *fp = fopen(nomefin,"r");

if (fp == NULL) {

printf("Erro na abertura do ficheiro %s\n", nomefin); exit(1);

} n = 0;

while ((c = fgetc(fp)) != EOF) {

if ((i = indicevogal(c)) != -1) freqabs[i].num++; n++;

}

fclose(fp); if (n != 0) {

for (i=0; i<5; i++)

printf("%c: %3.0f\045\n",freqabs[i].vog,(100.0*freqabs[i].num)/n); }

}

RESPOSTA ALTERNATIVA:

void frequencia(char *nomefin) { int freq[256]={0}, n, c;

char vogal[5]={’a’,’e’,’i’,’o’,’u’}; FILE *fp = fopen(nomefin,"r"); if (fp == NULL) {

printf("Erro na abertura do ficheiro %s\n", nomefin); exit(1);

(2)

n = 0;

while ((c = fgetc(fp)) != EOF) { freq[c]++; n++; } fclose(fp);

if (n != 0) {

for (c=0; c<5; c++)

printf("%c: %3.0f%%\n",vogal[c],(100.0*freq[(unsigned int)vogal[c]])/n); } } 2.

Resposta:

#ifndef FRAC_H #define FRAC_H #include <stdio.h>

typedef struct { int num, den; } FRAC; FRAC converter(int);

int zero(FRAC); // retorna 0 se n~ao for void imprimefrac(FRAC); FRAC soma(FRAC,FRAC); FRAC diferenca(FRAC,FRAC); FRAC produto(FRAC,FRAC); FRAC quociente(FRAC,FRAC); #endif 3.

Resposta:

#define DIGITO(D) ((D) >= ’0’ && (D) <= ’9’) FRAC avalia(struct arv *expr)

{ // assume expr != NULL e ´arvore bem constru´ıda FRAC x, y;

if (DIGITO(VALOR(expr))) return converter(VALOR(expr)-’0’); x = avalia(ESQUERDA(expr));

y = avalia(DIREITA(expr)); switch (VALOR(expr)) {

case ’*’: return produto(x,y); case ’+’: return soma(x,y); case ’-’: return diferenca(x,y);

default: if (zero(y)) { printf("ERRO divisao por 0\n"); exit(1); } return quociente(x,y);

} }

4.

Resposta:

O conte´udo de main.c #include <stdio.h> #include <stdlib.h> #include "frac.h"

(3)

#include "binarvores.h" #include "expressoes.h" int main()

{ struct arv *expr; char seq[30]; scanf("%s",seq);

expr = constroi_arv_expr(seq); // sup~oe-se definida em expressoes.h if (expr != NULL) { imprimefrac(avalia(expr)); putchar(’\n’); } return 0;

}

O conte´udo de expressoes.h #ifndef EXPRESSOES_H #define EXPRESSOES_H #include <stdio.h> #include <stdlib.h> #include "frac.h" #include "binarvores.h" FRAC avalia(struct arv *);

struct arv *constroi_arv_expr(char *); void imprime_expr(struct arv *); #endif

O ficheiro expressoes.c come¸caria por include "expressoes.h" e teria a seguir o c´odigo das fun¸c˜oes avalia, constroi_arv_expr e imprime_expr, bem como de fun¸c˜oes ou macros auxiliares, que venham a ser definidas para as implementar (como por exemplo, DIGITO(P)). O ficheiro binarvores.h teria essencialmente o que se descreve no enunciado e em binarvores.c estaria o c´odigo das fun¸c˜oes declaradas em binarvores.h (e doutras auxiliares que eventual-mente sejam definidas para as implementar).

——————————————————– FACULTATIVOPor exemplo, em binarvores.h teria #ifndef BINARVORES_H

#define BINARVORES_H #include <stdlib.h> struct arv {

char v;

struct arv *esq, *dir; };

#define VALOR(P) ((P) -> v); #define ESQUERDA(P) ((P) -> esq); #define DIREITA(P) ((P) -> dir);

struct arv *cria_no_arv(char val,struct arv *esquerdo,struct arv *direito); struct arv *remove_no_arv(struct arv *raiz,struct arv *no);

#endif

e em binarvores.c teria #include "binarvores.h" e a implementa¸c˜ao de cria_no_arv e de remove_no_arv.

(4)

Teria ainda o ficheiro frac.c onde colocaria #include "frac.h" e o c´odigo das fun¸c˜oes converter, . . . ,produto, quociente declaradas em frac.h.

O conte´udo do ficheiro Makefile era:

progr: binarvores.o expressoes.o main.o frac.o

gcc -o progr binarvores.o expressoes.o main.o frac.o frac.o: frac.c frac.h

gcc -c frac.c

binarvores.o: binarvores.c binarvores.h gcc -c binarvores.c

expressoes.o: frac.h binarvores.h expressoes.h expressoes.c gcc -c expressoes.c

main.o: frac.h binarvores.h expressoes.h main.c gcc -c main.c

clean:

rm *.o prog

5. (a)

Resposta:

typedef struct no {int prox; struct no *prox;} GRUPO, *PTR_GRUPO;

(b)

Resposta:

int i = grupos[’G’-’A’] -> pos;

Coloca em i o ´ındice da posi¸c˜ao que o primeiro elemento do grupo definido pela inicial G ocupa em alunos.

printf("%c\n", alunos[i][11]);

Imprime o caracter G (primeiro caracter do nome do aluno atr´as referido). printf("%s\n", &alunos[i][11]);

Imprime o nome do aluno que est´a na primeira posi¸c˜ao do grupo G. PTR_GRUPO lst = grupos[’G’-’A’];

Coloca em lst o endere¸co do primeiro n´o da lista que define o grupo G. printf("%s\n", alunos[lst -> prox ->pos]);

Imprime a informa¸c˜ao dispon´ıvel sobre o aluno que est´a na segunda posi¸c˜ao no grupo G. (c)

Resposta:

static void ordena(char *alunos[],int nalunos,struct no *grupos[26]) { int i;

agrupa(alunos,nalunos,grupos); for (i=0; i<26; i++)

grupos[i] = ordenaGrupo(grupos[i],alunos); }

(5)

(d)

Resposta:

void ordena_imprime(char *alunos[],int nalunos) { int i;

PTR_GRUPO grupos[26], aux; ordena(alunos,nalunos,grupos); for(i=0; i<26; i++) {

aux = grupos[i]; while(aux != NULL) {

printf("%s\n", alunos[aux -> pos]); aux = aux -> prox;

} } }

(e)

Resposta:

static void agrupa(char *alunos[],int nalunos, PTR_GRUPO grupos[26]) { int i;

for (i=0; i < 26; i++) grupos[i] = NULL; for (i=0; i < nalunos; i++)

grupos[Alunos[i][11]-’A’] = cria_no(i,grupos[Alunos[i][11]-’A’]); }

static PTR_GRUPO cria_no(int i, PTR_GRUPO g) { PTR_GRUPO novo = malloc(sizeof(GRUPO));

if (novo != NULL) { novo -> pos = i; novo -> prox = g; return novo; }

printf("Sem memoria\n"); exit(1); }

(f)

Resposta:

Por adapta¸c˜ao do algoritmo quicksort dado na disciplina. static PTR_GRUPO ordenaGrupo(PTR_GRUPO lstg,char *alunos[]) { PTR_GRUPO lmenor, lmaior_ig;

if (lstg == NULL) return NULL;

parte(lstg -> prox, lstg -> pos, &lmenor, &lmaior_ig,alunos); lmenor = ordenaGrupo(lmenor,alunos);

lmaior_ig = ordenaGrupo(lmaior_ig,alunos); lstg -> prox = lmaior_ig;

return concatena(lmenor,lstg); }

static void parte(PTR_GRUPO g,int i,PTR_GRUPO *lm,PTR_GRUPO *lMi,char *als[]) { *lm = *lMi = NULL; PTR_GRUPO aux; while(g != NULL) { aux = g -> prox; if (ordena_par(als[g->pos],als[i]) < 0) { g -> prox = *lm; *lm = g;

} else { g -> prox = *lMi; *lMi = g;} g = aux;

} }

(6)

PTR_GRUPO concatena(PTR_GRUPO lst1, PTR_GRUPO lst2) { if (lst1 == NULL) return lst2;

if (lst2 == NULL) return lst1;

lst1 -> prox = concatena(lst1 ->prox, lst2); return lst1;

}

(g)

Resposta:

Colocar #include <string.h> no cabe¸calho do m´odulo. // #define POR_NOMES

#ifdef POR_NOMES

int ordena_par(char *x,char *y) { // por nomes (crescente)

return strcmp(x+11,y+11); // ou return strcmp(&x[11],&y[11]); }

#else

int ordena_par(char *x,char *y) { // por codigos (decrescente) int rescomp; x[10] = y[10] = ’\0’; rescomp = strcmp(x,y); x[10] = y[10] = ’ ’; return -rescomp; } #endif

As duas vers˜oes ficam protegidas da forma indicada atr´as por directivas para o pr´e-processador: #ifdef POR_NOMES ... #else ... #endif. Se for retirado o coment´ario de // #define POR_NOMES e compilado o programa, a ordena¸c˜ao ser´a por ordem lexi-cogr´afica crescente de nomes. Caso contr´ario, ´e por ordem decrescente de c´odigos. Em alternativa, para evitar recompilar o programa e/ou para poder efectuar ordena¸c˜oes por v´arios crit´erios no mesmo programa, poder-se-ia ter colocado mais um parˆametro nas fun¸c˜oes ordenaGrupo, parte, ordena e ordena_imprime, para passar a ter (um apontador para) a fun¸c˜ao de ordena¸c˜ao como parˆametro dessas fun¸c˜oes. Por exemplo,

void ordena_imprime(char *alunos[],int nalunos,int (*ordlin)(char*, char*)) A fun¸c˜ao parte passaria a ser declarada por

static void parte(PTR_GRUPO g,int i,PTR_GRUPO *lm,PTR_GRUPO *lMi, char *als[], int (*ordlin)(char*, char*)) e, na sua defini¸c˜ao, substituiriamos a instru¸c˜ao

if (ordena_par(als[g->pos],als[i]) < 0) { por

if (ordlin(als[g->pos],als[i]) < 0) {

Deste modo, ´e poss´ıvel definir v´arios crit´erios para ordenar duas linhas (implementados por fun¸c˜oes com nomes distintos) e especificar em cada chamada de ordena_imprime qual a fun¸c˜ao que far´a a ordena¸c˜ao de duas linhas. Por exemplo, se as fun¸c˜oes que implementam os dois crit´erios acima tratados passassem a ser designadas por ordena1 e ordena2, podiamos chamar consecutivamente:

ordena_imprime(alunos,nalunos,ordena1); ordena_imprime(alunos,nalunos,ordena2);

Referências

Documentos relacionados

Em face dos objetivos anteriormente expostos, a base para o desenvolvimento desse trabalho foi o Software SIE - módulo biblioteca, ferramenta desenvolvida no Centro de Processamento

Neste trabalho, o potencial da técnica de Ressonância Magnética Nuclear (RMN) de baixo campo foi avaliado para o monitoramento da liberação de ferro a partir

Resultados: Actigym™ aumentou a atividade da enzima citrato sintase e portanto a função mitocondrial nas fibras musculares em 47,9%.. Produção de ATP nas

Para tanto foram analisados três episódios (“A visita”, “Porto Alegre” e “Economia Informal”) do programa “Central da Periferia – Minha Periferia”.. O

Como objetivos específicos, este estudo pretende: 1 Identificar o comportamento intraempreendedor dos profissionais de projetos; 2 Caracterizar o sucesso dos projetos cujos

Áreas com indícios de degradação ambiental solo exposto no Assentamento Fazenda Cajueiro A e no Assentamento Nossa Senhora do Carmo B, localizados, respectivamente, no Município de

A curva em azul é referente ao ajuste fornecido pelo modelo de von Bertalany, a curva em vermelho refere-se ao ajuste fornecido pelos valores calculados Lt, dados pela equação

Os estudos sobre diferenciais de salários são explicados por alguns fatores que revelam a existência da relação entre as características pessoais produtivas educação,