Baixe o projeto da lista, importe ele na Scala IDE (Eclipse), e implemente as funções
correspondentes a cada questão do exercício. Depois envie
apenas o arquivo package.scala
com os fontes da sua implementação até 02/12/2015,
usando esse link.
Uma representação para conjuntos é pela sua função característica, uma função
que diz se um elemento pertence ao conjunto ou não. Em Scala, um conjunto de
elementos de um tipo T
pode ser então dado pelo tipo de funções de T
para
booleanos:
type Conjunto[T] = T => Boolean
Por exemplo, o conjunto dos inteiros pares pode ser dado por (x: Int) => x % 2 == 0
.
Dada essa definição para conjuntos, a definição de uma função que verifica se um
conjunto contém ou não um elemento é trivial:
def contem[T](conj: Conjunto[T], elem: T) = conj(elem)
a) Defina uma função unitario
que cria um conjunto unitário:
def unitario[T](elem: T): Conjunto[T] = ???
b) Defina as funções uniao
, intesercao
e diferenca
, que fazem a união,
interseção e diferença de dois conjuntos:
def uniao[T](c1: Conjunto[T], c2: Conjunto[T]): Conjunto[T] = ???
def intersecao[T](c1: Conjunto[T], c2: Conjunto[T]): Conjunto[T] = ???
def diferenca[T](c1: Conjunto[T], c2: Conjunto[T]): Conjunto[T] = ???
c) Defina a função filtro
que retorna um conjunto contendo apenas os elementos do
conjunto que passam pelo filtro:
def filtro[T](c: Conjunto[T], f: T => Boolean): Conjunto[T] = ???
d) Defina a função map
que transforma um conjunto de elementos de tipo T
em um
conjunto de elementos de tipo U
, dada uma função de mapeamento U => T
:
def map[T, U](c: Conjunto[T], f: U => T): Conjunto[U] = ???
e) Por que a função de mapeamento para conjuntos tem os tipos trocados em relação à sua
equivalente no map
de listas? Responda em um comentário acima de sua implementação de map
.
Uma outra representação para conjuntos é como uma árvore binária de busca, que em Scala pode ser dada pelo tipo algébrico a seguir (para simplificar o problema, vamos tratar apenas de conjuntos de números inteiros):
trait ConjInt {
def contem(x: Int): Boolean = ???
def insere(x: Int): ConjInt = ???
def uniao(outro: ConjInt): ConjInt = ???
def filter(p: Int => Boolean): ConjInt = ???
def map(f: Int => Int): ConjInt = ???
def flatMap(f: Int => ConjInt): ConjInt = ???
}
case class ConjVazio() extends ConjInt
case class ConjCons(elem: Int, esq: ConjInt, dir: ConjInt) extends ConjInt
Implemente os métodos que estão definidos no tipo ConjInt
. Dica: a maneira mais
fácil de filtrar um conjunto é ir construindo um novo conjunto adicionando os elementos
que passam pelo predicado um a um.
Com as funções filter
, map
e flatMap
é possível usar a notação for
com geradores
do tipo ConjInt
. Implemente a função intersecao(c1: ConjInt, c2: ConjInt): ConjInt
usando a notação for
para filtrar o produto cartesiano dos dois conjuntos.
Última Atualização: 2016-05-18 10:58