Departamento de Ciˆ
encia de Computadores
Estruturas de Dados (CC114)
1
oTeste: 27/Abril/2011
FCUP
2010/11
dura¸c˜
ao: 2 horas
1. Teste A (indicar o teste que est˜
ao a fazer na folha de resposta)
2. Cota¸
c˜
ao de cada pergunta: 1. 35 / 2. 25 / 3. 40 (Total: 100 pontos)
3. Responda `
as quest˜
oes de forma clara e concisa nas folhas de exame distribu´ıdas.
1. (Valoriza¸
c˜
ao: 35%) Responda `
as seguintes quest˜
oes:
a) Analise o c´
odigo seguinte, ilustre como ficam em mem´
oria a representa¸
c˜
ao dos 3 vectores
e respectivos conte´
udos e diga o que ´
e escrito como resultado na ´
ultima linha de c´
odigo.
1. int a[]= {1,3,5,7,9,11};
2. int b[]= new int[6];
3. int c[]= new int[6];
4. b=a;
5. for (int i=0; i<a.length; i++)
6.
c[i]= a[i];
7. a[3]= c[5];
8. c[3]++;
9. System.out.println(a[3] + " " + b[3] + " " + c[3]);
Saliente-se que a atribui¸c˜ao b=a (linha 4.) faz com que as vari´aveis a e b referenciem o mesmo vector (o vector a dado inicialmente na linha 1.).
No ciclo-for (linhas 5 e 6) copia-se para o vector c os valores do vector a.
Na linha 7, muda-se o valor de a[3] (ou seja b[3]) ficando igual a 11 que est´a em c[5]. Na linha 8. incrementa-se o valor de c[3] passando para 8.
A linha 9 escreve como resultado: 11 11 8
Os vectores em mem´oria ficam como se ilustra na figura seguinte:
b) Escreva um m´
etodo recursivo com assinatura double somaReciprocos(int n) que aceita
como argumento um inteiro n˜
ao negativo (n > 0) e retorna um n´
umero em v´ırgula
flutu-ante (double) que ´
e a soma dos rec´ıprocos de 1 a n. Por exemplo, somaReciprocos(2)
retorna 1.5, que ´
e 1/1+1/2; e somaReciprocos(4) retorna aproximadamente 2.0833, que
´
e resultado de 1/1 + 1/2 + 1/3 + 1/4. Uma solu¸c˜
ao iterativa n˜
ao ser´
a considerada.
double somaReciprocos(int n) { if (n==1)
return 1;
return ((double)1/n) + somaReciprocos(n-1); }
c) Dˆ
e uma ideia breve de como funciona o m´
etodo de ordena¸
c˜
ao da “bolha” (bubble-sort) e
ilustre o seu funcionamento na ordena¸
c˜
ao da sequˆ
encia 8, 3, 7, 1, 4 (dever´
a mostrar
os sucessivos passos que o m´
etodo realiza).
O m´etodo da bolha faz a compara¸c˜ao dos elementos do vector dois a dois, de tal modo que ao fim da primeira itera¸c˜ao, i.e. (n-1) compara¸c˜oes, temos a garantia que o maior elemento (se estivermos a ordenar por ordem crescente) ter´a deslizado at´e `a ´ultima posi¸c˜ao do vector. Repetimos este processo no m´aximo mais (n-2) vezes para garantir que colocamos os restantes elementos na posi¸c˜ao correcta. A figura seguinte ilustra as sucessivas compara¸c˜oes:
2. (Valoriza¸
c˜
ao: 25%) Classes, vectores
A empresa WeBuyYourDebt tem um sistema de informa¸
c˜
ao para estar inteirada das cota¸
c˜
oes
(ratings) dados por agˆ
encias de nota¸
c˜
ao `
as diversas entidades a quem compra d´ıvida. Para
isso tem definidas duas classes: a classe Rating representa informa¸c˜
ao sobre a a agˆ
encia que
definiu a cota¸c˜
ao (nome), o n´ıvel da cota¸
c˜
ao (”AAA”, ”AA”, ”C”, etc), se a entidade em
quest˜
ao est´
a em vigilˆ
ancia pela agˆ
encia ou n˜
ao, e o valor decimal da taxa anual atribu´ıda de
acordo com a cota¸
c˜
ao; a classe BusinessEntity representa informa¸c˜
ao sobre uma entidade
alvo e as correspondentes cota¸
c˜
oes.
class BusinessEntity { Rating ratings[]; /**
* Usando os diversos ratings associados `a entidade, calcular a taxa de juro. A taxa * final ´e a m´edia dos diversos ratings acrescida de um spread definido como
* constante: GLOBAL_SPREAD (adicionado `a m´edia calculada). *
* No c´alculo da m´edia deve ter-se em conta se a entidade est´a em vigil^ancia (numa * watchlist). Se estiver, o valor do rating deve ser valorizado de WATCH_FACTOR * (ou seja multiplicado por).
*
* @return a taxa calculada */
public double calcInterestRate(); //...
}
Um exemplo de um objecto representado pela classe BusinessEntity seria a informa¸c˜
ao sobre
a CGD onde as v´
arias cota¸
c˜
oes seriam dadas pela S&P, Moody’s, etc.
a) Implemente a classe Rating e respectivo constructor.
O texto descreve 4 propriedades que caracterizam um rating, nomeadamente: • nome da agˆencia de nota¸c˜ao que deu o rating - uma String
• o n´ıvel de cota¸c˜ao que a agˆencia deu - uma String • tem a entidade sob vigilˆancia ou n˜ao - um boolean • taxa de juro atribu´ıda pela agˆencia - um double. Percebendo isto a classe pode ser representada por: class Rating{
String agenciaNotificacao; String cotacaoAtribuida; boolean emVigilancia; double taxaJuro;
Rating(String a, String c, boolean v, double t) { agenciaNotificacao= a;
cotacaoAtribuida= c; emVigilancia= v; taxaJuro= t; }
// neste caso n~ao defini atributos privados pelo que n~ao // n~ao preciso de m´etodos de acesso ou de modifica¸c~ao }
b) Implemente o m´
etodo calcInterestRate() que calcula a taxa de juro a aplicar `
a entidade
de acordo as regras definida na documenta¸
c˜
ao dada.
O problema consiste essencialmente em calcular uma m´edia de um conjunto de valores. Cada valor antes de ser usado pode ter de ser multiplicado pelo WATCH FACTOR. Ao valor final de m´edia temos de acrescentar o valor do GLOBAL SPREAD.
class BusinessEntity { Rating ratings[];
public double calcInterestRate() { double taxa= 0;
double watchFactor;
int numRatings= ratings.length; // primeiro somamos todas as taxas for (int i=0; i< numRatings; i++) {
// verificar se um dado rating deve ser valorizado if (ratings[i].emVigilancia)
watchFactor= WATCH_FACTOR; else
watchFactor= 1; // elemento neutro na multiplica¸c~ao // calcula a soma acumulada das taxas de juro
taxa= taxa + ratings[i].taxaJuro*watchFactor; }
// por fim calcula a m´edia acrescida do spread taxa= taxa/numRatings + GLOBAL_SPREAD;
return taxa; }
}
3. (Valoriza¸
c˜
ao: 40%) Classes e Listas
A liga dos campe˜
oes (champions league), organizada pela UEFA, ´
e uma prova de selec¸
c˜
ao por
etapas ou fases que levam ao apuramento do campe˜
ao europeu de um determinado ano. A
primeira etapa importante ´
e uma fase de qualifica¸
c˜
ao (play-offs) que envolve algumas equipas
campe˜
as de alguns pa´ıses e outras que poder˜
ao ser segundos ou terceiros classificados nas suas
ligas. Seguem-se outras etapas, fase de grupos com todas as equipas de um grupo a jogarem
entre si, fase de eliminat´
orias e a final.
Em cada etapa existe um conjunto de jogos realizados. De cada jogo registamos o nome da
equipa visitada, o n´
umero de golos marcados pela equipa visitada, o nome da equipa visitante,
e o n´
umero de golos da equipa visitante.
Tendo em vista o registo dos resultados em mem´
oria para efeitos de elabora¸c˜
ao de listagens
v´
arias, concebeu-se uma estrutura de dados conforme se ilustra na figura seguinte:
a) Os jogos que acontecem numa dada etapa s˜
ao guardados numa lista ligada simples.
De-fina uma classe gen´
erica LList<E> que implemente uma lista ligada simples, incluindo a
implementa¸c˜
ao dos m´
etodos construtores e a implementa¸
c˜
ao de um m´
etodo para adicionar
um novo elemento no in´ıcio da lista.
Usando a defini¸c˜ao dada nas aulas, precisamos de duas classes, uma a caracterizar um n´o e outra a caracterizar a lista. Por simplicidade, e dado que n˜ao se pede no enunciado, n˜ao usamos atributos privados na classe que caracteriza um n´o da lista, algo que deve ser feito numa solu¸c˜ao mais geral: class Node<E> { E val; Node<E> next; Node(E v, Node<E> n) { val= v; next= n; } } class LList<E> { Node<E> first; int size;
LList() { // construtor de lista vazia first= null;
size= 0; }
boolean isEmpty() {return size==0;}
// adicionar na 1a posicao consiste em criar um novo n´o
// cujo atributo next referencie actual primeiro, ficando este // novo n´o a ser o primeiro n´o da lista
void addFirst(E v) {
first= new Node<E>(v,first); size++;
} }
b) A ilustra¸c˜
ao mostra claramente um vector de objectos de uma classe Etapa que por sua
vista faz referˆ
encia a objectos de uma classe Jogo. Defina as duas classes, incluindo os
m´
etodos construtores correspondentes.
Deve usar a defini¸
c˜
ao gen´
erica anterior de lista, caso n˜
ao tenha respondido `
a pergunta
anterior pode usar a classe correspondente do Java.
Um objecto da classe Etapa precisa de ter apenas dois atributos, um nome da etapa (uma string) e uma referˆencia para uma lista ligada com os jogos:
class Etapa {
String nome; // Qualific, Grupos, Elimina, Final LList<Jogo> jogos; // ser´a a lista ligada de jogos Etapa(String n) {
nome= n;
jogos= new LList<Jogo>(); // inicialmente fica lista vazia }
}
A classe Jogo ´e muito simples e tem quatro atributos, os nomes das equipas e os golos que cada equipa marcou.
class Jogo {
String eqVisitada; // nome da equipa visitada int golosVisitada; // golos da equipa visitada String eqVisitante; // nome da equipa visitante int golosVisitante; // golos da equipa visitante Jogo(String casa, int gCasa, String fora, int gFora) {
eqVisitada= casa; golosVisitada= gCasa; eqVisitante= fora; golosVisitante= gFora; } }
c) Implemente na classe Etapa um m´
etodo para inserir a informa¸c˜
ao de um jogo novo. A
as-sinatura do m´
etodo dever´
a ser: void adicionaJogo(String eqCasa, int golosCasa,
String eqFora, int golosFora);, onde os argumentos representam a informa¸
c˜
ao
rela-tiva ao jogo.
A implementa¸c˜ao deste m´etodo requer apenas a cria¸c˜ao de um objecto jogo e adicion´a-lo `a lista, por exemplo no in´ıcio da lista. Lembrar que estamos na classe Etapa.
class Etapa {
String nome;
LList<Jogo> jogos;
void adicionaJogo(String eqCasa, int golosCasa, String eqFora, int golosFora) { jogos.addFirst(new Jogo(eqCasa, golosCasa, eqFora, golosFora));
} }