Fundamentosde Programação
Soluçãodo segundoteste
16 de Janeirode 2006
Nota
9:00-10:30
Número:
Nome:
Turma:
Escreva o seu número em todas as folhas do teste. O espaço das respostas deve ser limitado ao
espaço fornecido para cada pergunta. O teste tem 9 páginas com 11 questões; a cotação de
cada questão encontra-se indicada entre parêntesis. Boa sorte!
Questão Cotação Classificação
1
1.5
2
1
3
1.5
4
1.5
5
1.5
6
1
7
1.5
8
3
9
2
10
2
11
3.5
1. (1.5) Diga quais as fases do desenvolvimento de um programa, descrevendo sucintamente (2 a
3 linhas) cada uma delas.
● Análise do problema: o programador, juntamente com o cliente, estuda o problema a resolver
●
●
●
●
com o objectivo de determinar exactamente o que o programa deve fazer.
Desenvolvimento de uma solução: determinação de como vai ser resolvido o problema.
Desenvolvimento de um algoritmo e definição abstracta dos tipos de informação usados. Deve
usar-se a metodologia do topo para a base. Vantagens: controle da complexidade e obtenção
de um algorimo modular.
Codificação da solução: 1) tradução do algoritmo para uma LP, e implementação dos tipos de
informação; 2) depuração, i.e., correcção de erros sintácticos e semânticos; 3) finalização da
documentação que vem sido produzida desde a primeira fase.
Testes: definição de uma bateria de testes com o objectivo de “garantir” que o programa
funciona correctamente em todas as situações possíveis.
Manutenção: fase que decorre depois do programa estar em funcionamento. A manutenção
pode ser necessária por dois tipos de razões: 1) descoberta de erros; 2)
modificações/actualizações nas especificações do programa.
2. (1.0) Diga o que entende por objecto com estado. Como é caracterizado esse estado?
Um objecto com estado é um objecto cujo comportamento depende da sua história. O seu
estado é caracterizado por uma ou mais variáveis de estado.
Pág. 3/11
AlunoNº __________________
3. (1.5) Diga quais os métodos de passagem de parâmetros que estudou, descrevendo cada um
deles.
Foram estudados dois métodos de passagem de parâmetros, i.e., formas de associar os
parâmetros concretos aos parâmetros formais:
● Passagem por valor: a cada parâmetro formal é associado o valor do parâmetro concreto
correspondente. Método unidireccional: a alteração do parâmetro formal não afecta o
parâmetro concreto.
● Passagem por referência: a cada parâmetro formal é associada a localização em memória
do parâmetro concreto correspondente. Método bidireccional: uma vez que o parâmetro
formal e o parâmetro concreto ocupam a mesma zona de memória, a alteração do
parâmetro formal afecta o parâmetro concreto.
4. (1.5) Qual o método de gestão de memória usado em Scheme? Descreva esse método.
É o método da recolha de lixo (“garbage collection”). Este método é aplicado quando a
quantidade de memória disponível no amontoado desce para além de um determinado limiar, e
tem duas fases:
● Fase de marcação: todas as células de memória que podem ser alcançadas a partir do
ambiente global, ou de informação mantida pelo interpretador, são marcadas como não
sendo lixo.
● Fase de varrimento: todas as células de memória (das inicialmente atribuídas ao amontoado)
que não foram marcadas na fase anterior são devolvidas ao amontoado.
Pág. 4/11
AlunoNº __________________
5. (1.5) Diga quais os paradigmas de programação que estudou e caracterize cada um deles.
● Programação funcional: os programas são encadeamentos de procedimentos, cada um dos
quais devolve um valor, como uma função matemática.
● Programação imperativa: os programas são sequências de instruções, cada uma das quais
produz um efeito, i.e., altera uma entidade computacional.
● Programação com objectos: baseada na noção de objecto, i.e., entidade computacional que
apresenta um estado (caracterizado por um conjunto de variáveis de estado) e um conjunto de
procedimentos que permitem manipular esse estado, designados por métodos. Os objectos
recebem mensagens, e usam o método adequado para responder a cada tipo de mensagem.
6.
(1.0) Escreva um procedimento que recebe um vector de inteiros e devolve o produto dos
elementos do vector.
(define (produto-elementos-vector v)
(define (produto-aux v corrente ultimo-el prod-ac)
(if (> corrente ultimo-el)
prod-ac
(produto-aux v
(+ corrente 1)
ultimo-el
(* (vector-ref v corrente) prod-ac))))
(let ((ultimo-el (- (vector-length v) 1)))
(produto-aux v 0 ultimo-el 1)))
Pág. 5/11
AlunoNº __________________
7. (1.5) Considere a seguinte definição:
> (define (soma-lista lst)
(define (soma-aux lst total)
(if (null? lst)
total
(soma-aux (rest lst)
(+ (first lst) total))))
(soma-aux lst 0))
Desenhe o diagrama de ambientes originados pela avaliação da forma
(soma-lista '(1 2))
Análogo ao exemplo apresentado na secção 8.3.3 do livro
(avaliação com definições internas – processo iterativo)
Pág. 6/11
AlunoNº __________________
8. Considere a seguinte interacção:
> (define est1 (cons 1 (cons 2 ())))
> (define est2 (cons 1 (cons 2 ())))
a) (1.0) Desenhe, usando a notação de caixas e ponteiros, as estruturas criadas.
est1
> 1
> 2
est2
>
1
> 2
b) (0.5) Qual o valor devolvido por cada uma das seguintes expressões?
> (equal? est1 est2)
#t
> (eq? est1 est2)
#f
c) (1.0) Represente as alterações produzidas nas estruturas pela seguinte interacção:
> (define p (cons 0 ()))
> (set-cdr! (cdr est1) p)
> (set-cdr! (cdr est2) est1)
est1
>
p
1
> 2
1
> 2
> 0
est2
>
d) (0.5) Qual o valor devolvido por cada uma das seguintes expressões?
> est1
(1 2 0)
> est2
(1 2 1 2 0)
9. (2.0) Defina um procedimento chamado transforma! que recebe como argumentos uma
lista e uma operação aplicável aos elementos da lista. O seu procedimento deve alterar
destrutivamente a lista recebida, aplicando a operação a todos os elementos dessa lista. Por
exemplo,
> (define lst (list 1 2 3))
> (transforma! lst (lambda (x) (* 3 x)))
> lst
(3 6 9)
(4
Pág. 7/11
AlunoNº __________________
(define (transforma! lst op)
(if (not (null? lst))
(begin
(set-car! lst (op (car lst)))
(transforma! (cdr lst) op))))
10. (2.0) Defina uma classe que corresponde a uma urna de votação. A sua classe deve receber a
lista dos possíveis candidatos e manter como estado interno o número de votantes em cada
candidato. Os elementos desta classe podem receber dois tipos de mensagens: 1) o nome de um
candidato (um símbolo), aumentando em 1 o número de votos nesse candidato; 2) o símbolo
resultado, devolvendo os resultados da votação até ao momento (use o comando display
para mostrar os resultados). Por exemplo,
> (define urna (cria-urna '(A B C))
> (urna 'resultados)
c – 0
b - 0
a - 0
> (urna 'C)
> (urna 'A)
> (urna 'B)
> (urna 'A)
> (urna 'B)
> (urna 'A)
> (urna 'C)
> (urna 'A)
> (urna 'resultados)
c – 2
b - 2
a - 4
Pág. 8/11
AlunoNº __________________
(define (cria-urna candidatos)
;o procedimento seguinte devolve uma lista em que cada elemento
; é um par cujo 1ºelemento é o nome do candidato e o 2º o nº de
;votos no candidato (zero no início). Por exemplo,
; (inicializa-resultados '(A B C)) devolve ((c . 0) (b . 0) (a . 0))
(define (inicializa-resultados candidatos)
(define (inicializa-aux candidatos resultados)
(if (null? candidatos)
resultados
(inicializa-aux (rest candidatos)
(cons (cons (first candidatos) 0)
resultados))))
(inicializa-aux candidatos ()))
(let ((resultados (inicializa-resultados candidatos)))
(define (vota cand resultados)
(if (eq? cand (car (first resultados)))
(set-cdr! (first resultados)
(add1 (cdr (first resultados))))
(vota cand (rest resultados))))
(define (mostra-resultados resultados)
(if (not (null? resultados))
(begin
(display (car (first resultados)))
(display " - ")
(display (cdr (first resultados)))
(display "
")
(mostra-resultados (rest resultados)))
(newline)))
(lambda (mens)
(cond ((member mens candidatos)
(vota mens resultados))
((eq? mens 'resultados)
(mostra-resultados resultados))
(else (error "urna: pedido desconhecido"))))))
Pág. 9/11
AlunoNº __________________
11.
a) (1.5) Considere o tipo de informação info-aluno, cujos elementos são constituídos por um
número de aluno (um inteiro), e o nome do aluno (uma “string”). Defina o tipo abstracto de
informação info-aluno.
1) Definição das operações básicas:
Construtor:
cria-info-aluno: |N x string --> info-aluno
cria-info-aluno(num, nome) devolve o elemento do tipo info-aluno cujo número é num, e cujo
nome é nome.
Selectores:
número-aluno: info-aluno --> |N
número-aluno(aluno) devolve o número do aluno aluno.
nome-aluno: info-aluno --> string
nome-aluno(aluno) devolve o nome do aluno aluno.
Reconhecedor:
info-aluno?: universal --> lógico
info-aluno?(x) devolve verdadeiro se e só se x for do tipo info-aluno.
Teste:
alunos=?: info-aluno x info-aluno --> lógico
alunos=?(al1, al2) devolve verdadeiro se e só se al1 e al2 representarem o mesmo aluno.
2) Representação interna: Um elemento do tipo info-aluno é representado por um par cujo
primeiro elemento é o número do aluno e cujo segundo elemento é o nome do aluno.
3) Implementação das operações básicas:
(define cria-info-aluno cons)
(define numero-aluno car)
(define nome-aluno cdr)
(define (info-aluno? x)
(and (pair? x)
(integer? (car x))
(string? (cdr x))))
(define alunos=? equal?)
Pág. 10/11
AlunoNº __________________
Pág. 11/11
AlunoNº __________________
b) (2.0) Escreva um procedimento, procura, que recebe uma árvore binária de procura cujas
raízes são do tipo info-aluno, e um inteiro, e procura na árvore o aluno que tem como
número o inteiro recebido, devolvendo o seu nome. Se não for encontrado nenhum aluno com
o número dado, o seu procedimento deve devolver a “string” vazia. O algoritmo de procura
na árvore deve tirar partido do facto de se tratar de uma árvore binária de procura. A árvore foi
criada usando o número de aluno como elemento a comparar.
(define (procura arv num)
(cond ((arvore-vazia? arv) "")
((= num (numero-aluno (raiz arv)))
(nome-aluno (raiz arv)))
((< num (numero-aluno (raiz arv)))
(procura (arv-esq arv) num))
(else (procura (arv-dir arv) num))))
Download

Solução do 2º teste