PARA A RESOLUÇÃO DO EXAME, ACONSELHASE QUE LEIA ATENTAMENTE O SEGUINTE: NORMAS: 1) O exame tem a duração de 150 minutos. 2) O exame é feito SEM CONSULTA. 3) Deve assinalar todas as opções tomadas: no código dos seus programas, todas as constantes, variáveis, procedimentos ou funções devem ser devidamente explicadas através de comentário. 4) As respostas, que embora, sintáctica e semanticamente correctas, se apresentem pouco estruturadas serão severamente penalizadas, ou não consideradas. 5) As respostas de conteúdo inadequado não serão consideradas. 6) As respostas sem justificação serão fortemente penalizadas. INFORMAÇÕES: 1) Antes de começar a responder, leia todo o enunciado. Verifique se o exemplar está completo, isto é, se tem 9 páginas numeradas e termina com a palavra FIM . 2) No caso de o exemplar que lhe foi distribuído estar incompleto, ou tiver qualquer falha, dirijase ao professor vigilante, a fim de resolver o problema. 3) Qualquer aspecto que considere menos claro deverá ser explicado em comentário no código. A clareza da sua solução, o seu rigor científico e legibilidade constituem critérios de avaliação de máxima importância.
4) O exame é constituído por quatro questões a primeira com quatro alíneas, a segunda com três alíneas, a terceira questão com duas alíneas e a quarta questão com uma alínea. 5) Em caso de dúvida ou omissão resultante do enunciado de exame, a sua interpretação, quando devidamente explicada e enquadrada nos objectivos de avaliação da questão em causa, será considerada na avaliação da sua resposta. Bom Trabalho!
1º Problema (5 Valores)
Considere a classe Comboio a seguir definida: class Comboio
{
private:
std::string empresa; // Nome da empresa proprietária int milhas; // Número de milhas desde a ultima revisão int numero; // Número do comboio
public:
static int periodoRevisao; // Período de revisão do comboio em milhas Comboio();
Comboio (int onumero, std::string aempresa);
Comboio(const Comboio& other); //Construtor por cópia virtual ~Comboio();
virtual int Numero() const;
virtual std::string Empresa() const; virtual int MilhasPercorridas() const;
virtual bool RequerRevisao(); // Indica se o comboio necessita de revisão. virtual void ResetRevisao(); // Reinicializa o contador de milhas percorridas; virtual void AdicionaMilhas(int mil); /* Acrescenta as milhas indicadas ao contador de milhas percorridas */
virtual void DefinePeriodoRevisao(int mil); /* Define o período de revisão do comboio */
virtual void EscreveDados(); }; a) Implemente os construtores e o destrutor da classe. Espaço de resposta à questão 1a) Comboio: :Comboio( ) { }
Comboio: :Comboio( in t onumero, std: : s t r i ng aempresa): numero(onumero),
empresa(aempresa), milhas(0)
{}
Comboio: :Comboio(const Comboio& other) {
this - >numero=other.numero; this - >empresa=other.empresa; this - >milhas=other.mi lhas ; }
b) Defina os seguintes selectores desta classe virtual int Numero() const;
virtual std::string Empresa() const; virtual int MilhasPercorridas() const; Espaço de resposta à questão 1b) int Comboio: :Numero() const {
return numero; }
std: : s t r i ng Comboio: :Empresa() const {
return empresa; }
int Comboio: :Mi lhasPercorr idas ( ) const {
return milhas; }
c) Defina os métodos:
virtual void ResetRevisao(); // Reinicializa o contador de milhas percorridas; virtual void AdicionaMilhas(int mil); /* Acrescenta as milhas indicadas ao contador de milhas percorridas */
virtual void DefinePeriodoRevisao(int mil); /* define o período de revisão do comboio */
Espaço de resposta à questão 1c)
void Comboio: :Def inePer iodoRevisao( in t mil) {
periodoRevisao=mil ; }
void Comboio: :ResetRevisao( ) {
milhas=0; }
void Comboio: :Adic ionaMi lhas( in t mil) {
d) Defina o método:
virtual bool RequerRevisao(); /* Indica se o comboio necessita de revisão, com base no valor da variável estática periodoRevisao */
Espaço de resposta à questão 1d) bool Comboio: :RequerRevisao( ) { i f (milhas>=periodoRevisao) return true; else return fa lse ; } 2º Problema (6 Valores) Considere uma classe Horario para representar os horários e destinos dos comboios num dado dia. Cada comboio é identificado pelo índice no respectivo vector, assim sendo o comboio na posição 0 do vector combs, parte à hora indicada na posição 0 do vector horap, chega à hora indicada na posição 0 do vector horac. O local de origem e destino é indicado pelas posições 0 dos vectores origem e destino. As horas de partida e chegada de cada comboio são guardadas num formato minutos, que representa o número de minutos passados desde as 00:00 desse dia. (um comboio que parta às 06:12 terá como hora de partida no formato minutos 612)
class Horario {
private:
std::vector<Comboio> combs; // Vector com os comboios
std::vector<int> horap; // hora de partida de cada comboio no formato minutos std::vector<int> horac; /* hora de chegada de cada comboio no formato minutos */
std::vector<std::string> origem; // Local de partida de cada comboio std::vector<std::string> destino; // Local de Chegada de cada comboio public:
Horario();
virtual int converte(int horas, int minutos); virtual ~Horario();
virtual void AdicionaComboio(const Comboio& cb,int hp, int mp, int hc, int mc, std::string ori,std::string dest);
virtual void ListaComboiosRevisao(); /* Indica todos os comboios a necessitarem de revisão com base no definido na classe Comboio */
virtual void ListaComboiosDestino(std::string odestino); /* Indica todos os comboios para o destino odestino */
virtual void ListaComboios(std::string odestino, int hora); /* Indica todos os comboios para o destino odestino que chegam antes da hora hora */
virtual void ListaRapido(std::string odestino); /* Indica o comboio mais rápido para o destino destino. */
};
a) Implemente o método converte, que dada uma hora e minutos, converte esse valor no número de minutos passados desde as 00:00 (Ex: 12 horas e 12 minutos corresponde a 732 minutos)
Espaço de resposta à questão 2a)
int Companhia: :converte( in t horas, int minutos) {
return horas*60 + minutos; }
b) Implemente o método AdicionaComboio que dado um comboio com as horas e minutos de partida e chegada, assim como a origem e o destino adiciona um novo comboio.
virtual void AdicionaComboio(const Comboio& cb,int hp, int mp, int hc, int mc, std::string ori,std::string dest);
Espaço de resposta à questão 2b)
void Companhia: :Adic ionaComboio(const Comboio& cb, int hp, int mp, int hc, int mc, std: : s t r i ng ori , s td : : s t r i ng dest) { combs.push_back(cb) ; horap.push_back(converte(hp,mp)) ; horac.push_back(converte(hc ,mc)) ; origem.push_back(or i ) ; dest ino.push_back(dest) ; } c) Implemente os métodos:
virtual void ListaComboiosRevisao();
virtual void ListaComboiosDestino(std::string odestino); virtual void ListaComboios(std::string odestino, int hora); virtual void ListaRapido(std::string odestino);
Espaço de resposta à questão 2c)
void Companhia: :L i s taComboiosRevisao( ) {
for( in t counter=0; counter<combs.s ize( ) ; counter++) i f ( combs[counter] .RequerRevisao( ) )
void Companhia: :L i s taComboiosDest ino(s td : : s t r i ng odest ino) {
for( in t counter=0;counter<combs.s ize( ) ; counter++) i f (dest ino[counter]==odestino)
{
std: :cout << combs[counter] .Numero() << horap[counter] << horac[counter] ;
std: :cout << origem[counter] << dest ino[counter] << std: :endl ;
} }
void Companhia: :L i s taComboios(s td : : s t r i ng odest ino, int hora)
{
for( in t counter=0;counter<combs.s ize( ) ; counter++) i f ( ( des t ino[counter]==odestino) &&
(horac[counter]<=hora)) {
std: :cout << combs[counter] .Numero() << horap[counter] << horac[counter] ;
std: :cout << origem[counter] << dest ino[counter] << std: :endl ;
} }
void Companhia: :L i s taRapido(s td : : s t r i ng odest ino) {
int index=0;
int min =horac[0] - horap[0] ;
for( in t counter=1;counter<combs.s ize( ) ; counter++) i f (dest ino[counter]==odestino)
{
int tempo = horac[counter] - horap[counter] ; i f (tempo<min) { min=tempo; index=counter; } }
std: :cout << combs[index] .Numero() << horap[ index] << horac[ index] ;
std: :cout << origem[index] << dest ino[ index] << std: :endl ;
3º Problema (5 Valores)
Implemente em C++ uma classe ComboioDiesel, derivada de Comboio, para representar os comboios que são movidos a combustível líquido. Para esses comboios é preciso saber também o seu consumo em litros por cada 100 milhas (consumo), a capacidade em litros do depósito de combustível (capacidade) e o combustível que ainda resta no tanque (litros). Crie os dois construtores habituais, destrutor e selectores apropriados. Implemente também os seguintes métodos:
• void AdicionaMilhas (int mi) /* Para além de fazer o mesmo que na classe ascendente, reduz o combustível existente no depósito, com base no consumo conhecido; */
• void EncheDeposito(int quantidade) /* Enche o depósito com o valor de litros indicado por quantidade, mas garantindo que no máximo o depósito não excede a sua capacidade; */
• double Autonomia() /* Devolve o número de milhas que o comboio pode percorrer com o combustível restante; */ • bool RequerRevisao() /* Aplica a mesma regra da classe ascendente (revisão periódica) ou que deve ocorrer sempre que o combustível no depósito atinge a “reserva” (1/10 da capacidade total). */ a) Implemente a declaração da classe Espaço de resposta à questão 3a) class Fuel : publ ic Comboio { private : int consumo; int capacidade; double restante; publ ic : Fuel( ) ;
Fuel( in t num, std: : s t r i ng emp, int cons, int cap); Fuel(const Fuel& other) ;
vir tua l ~Fuel( ) ;
vir tua l int Consumo() const; vir tua l int Capacidade() const; vir tua l double Restante( ) const;
vir tua l void Adic iona Milhas( in t miles) ; vir tua l void EncheDeposito( in t amount); vir tua l double Autonomia() ;
vir tua l bool RequerRevisao() ; };
b) Implemente os métodos:
void AdicionaMilhas (int mi)
void EncheDeposito(int quantidade) double Autonomia()
bool RequerRevisao() Espaço de resposta à questão 3b)
void Fuel : :Ad ic ionaMi lhas( in t miles) {
Adic ionaMilhas(mi les ) ;
restante- =miles*consumo/100; }
void Fuel : :EncheDeposito( in t amount) { i f (restante+amount> capacidade) restante=capacidade; else restante+=amount; }
double Fuel : :Autonomia() {
return restante*100/consumo; }
bool Fuel : :RequerRevisao( ) {
i f (( res tante==capacidade/10) | | MilhasPercorr idas ( )>per iodoRevisao) return true;
else
return fa lse ; }
4º Problema (4 Valores)
Considere a classe IntList, estudada no livro da cadeira, para a manipulação de uma Lista de inteiros ordenados e sem repetições.
class IntList {
struct IntNode {// Classe interna para os nós da lista. int data;
IntNode* ptNext;
IntNode(int n) { data = n; }// Construtor com int n. };
IntNode* ptList; // Apontador para o primeiro nodo. bool find(int v, IntNode *&prev, IntNode *&curr) const; // Inviabilizar a construção por cópia e a afectação. IntList (const IntList&) {} // Construtor por cópia. void operator=(const IntList &) {} // Afectação. public:
IntList();// Iniciar a lista.
~IntList() { removeAll(); } // Destruir todos os nós. bool insert(int val); // Inserir ordenado.
bool remove(int val); // Remover se existir. int removeHead(); // Remover o 1º nodo da lista. bool contain(int val) const; // Testar se existe val. void display() const; // Apresenta os elementos. bool isEmpty() const; // Testar se lista está vazia. void removeAll(); // Remover todos os elementos. };
a) Implemente um método para testar se duas listas são iguais ou seja contêm exactamente os mesmos elementos.
Bool isEqual(const IntList&) const; Espaço de resposta à questão 4a)
bool IntL i s t : : i s Equal ( const IntL i s t& l1) const {
IntNode *la=ptL is t ; IntNode *lb=l1.ptL i s t ; do {
i f ( l a - >data !=lb- >data) return fa lse ; la=la- >ptNext; lb=lb- >ptNext; } while( la !=NULL); return true; } FIM