MAB 240 - Computação II

Revisão P1 - 10/10/2016

O padrão enumerador é uma maneira de se percorrer uma sequência de elementos. Um objeto enumerador possui dois métodos, um produz os elementos da sequência um por um, dando um erro se já produziu o último elemento, e o outro diz se já se chegou ao final da sequência ou não. Enumeradores para sequências de inteiros podem ser modelados pela seguinte interface:

interface Enumerador {
    int proximo();
    boolean fim(); 
}

1. Defina a classe EnumVetor, que implementa Enumerador e representa um enumerador para um vetor de inteiros passado no construtor. O trecho a seguir mostra um uso desse enumerador:

Enumerador e = new EnumVetor(new int[] { 1, 3, 5 });
System.out.println(e.proximo()); // imprime 1
System.out.println(e.fim()); // imprime false
System.out.println(e.proximo()); // imprime 2
System.out.println(e.proximo()); // imprime 3
System.out.println(e.fim()); // imprime true

2. Escreva o corpo da função abaixo, que recebe um enumerador e retorna uma lista com todos os elementos que ele pode produzir:

static java.util.List<Integer> listaDeEnum(Enumerador e) {
    // corpo
}

Imagine que temos a seguinte interface Lista para listas de inteiros:

public interface Lista {
    int quantos();     // quantos elementos a lista tem
    int soma();        // soma dos elementos da lista
    Enumerador enumerador(); // um enumerador para essa lista
}

3. Implemente a classe ListaVazia, que implementa Lista e representa uma lista sem elementos. Você vai precisar de uma implementação para Enumerador, experimente usar tanto a própria classe ListaVazia quanto uma classe auxiliar. O enumerador de uma lista vazia já começa com fim() retornando true.

4. Implemente a classe ListaCons, que também implementa Lista. Essa classe deve ter dois campos: o campo primeiro, de tipo int, que é o primeiro elemento da lista, e o campo resto, de tipo Lista, que é o resto da lista. Novamente, você também vai precisar implementar Enumerador. O enumerador de uma ListaCons produz o primeiro elemento, depois “vira” o enumerador do resto da lista (passa a delegar proximo() e fim() para esse enumerador).

Não é estritamente necessário dar nome para uma nova classe para implementar o enumerador de ListaCons, você pode usar uma classe anônima:

public Enumerador enumerador() {
    return new Enumerador() {
        // campos

        public int proximo() {
          // implementação de proximo
        }

        public boolean fim() {
          // implementação de fim
        }
    };
}

Um exemplo de uso de ListaCons e ListaVazia, para representar a lista 1, 3, 5:

Lista l = new ListaCons(1, new ListaCons(3, new ListaCons(5, new ListaVazia())));
System.out.println(l.soma()); // 9
System.out.println(l.quantos()); // 3
Enumerador e = l.enumerador();
System.out.println(e.fim()) // false
System.out.println(e.proximo()); // 1
System.out.println(e.fim()) // false
System.out.println(e.proximo()); // 3
System.out.println(e.fim()) // false
System.out.println(e.proximo()); // 5
System.out.println(e.fim()) // true

5. Implemente a classe ListaConcat, que também implementa Lista, e possui dois campos, lista1 e lista2, ambos do tipo Lista. ListaConcat representa a concatenação dessas duas listas. Pense em como implementar um enumerador para essa lista.

Lista l1 = new ListaCons(1, new ListaCons(3, new ListaCons(5, new ListaVazia())));
Lista l2 = new ListaCons(2, new ListaCons(4, new ListaCons(6, new ListaVazia())));
Lista l3 = new ListaConcat(l1, l2);
System.out.println(l3.quantos()); // 6
System.out.println(l3.soma()); // 21
Enumerador e3 = l3.enumerador();
while(!e3.fim()) System.out.println(e3.proximo()); // 1 3 5 2 4 6

6. Implemente a classe ListaPG, que também implementa Lista e representa uma progressão geométrica. ListaPG tem três campos, a0, do tipo int, que é o elemento inicial, q, a razão da progressão, e n, também do tipo int, o número de termos. Novamente, também implemente um enumerador para essa lista.

Lista l1 = new ListaPG(2,4,5);
System.out.println(l1.quantos()); // 5
System.out.println(l1.soma()); // 682
Enumerador e1 = l1.enumerador();
while(!e1.fim()) System.out.println(e1.proximo()); // 2 8 32 128 512

Última Atualização: 2016-12-09 11:49