Un conjunto es una colección finita o infinita de objetos en la que el orden no tiene significado, y la multiplicidad se ignora generalmente.
Wolfram MathWorld
Vamos a modelar conjuntos -finitos-, con todas las operaciones que éstos pueden llevar a cabo. Por supuesto podríamos modelar conjuntos infinitos, pero eso lo dejamos como ejercicio adicional para quien desee realizarlo.
Greg Cantor publicó, a fines del siglo XIX un paper que daría inicio a lo que hoy denominamos "Teoría de conjuntos". Su trabajo inicialmente dividió a sus contemporáneos: estaban los que lo apoyaban, y aquellos que no.
Con el correr del tiempo su teoría fue tomando fuerza, y se pudo emplear para hacer todo tipo de demostraciones matemáticas... así como también para dar origen a las paradojas (famosa es la de Bertrand Russell: "el conjunto de todos los conjuntos que no son miembros de sí mismos, ¿debe ser miembro de él mismo?", más conocida como la paradoja del barbero).
Los conceptos básicos de la teoría de conjuntos pueden verse en Wikipedia. Sin embargo, haremos aquí un breve reconto de las relaciones que deseamos implementar.
- Pertenencia: Es la relación que hay entre un elemento y el conjunto que lo contiene.
- Igualdad: La igualdad entre conjuntos verifica que ambos tengan exactamente los mismos elementos.
- Inclusión: Un conjunto incluye a otro si el primero contiene a todos los elementos del segundo.
Adicionalmente a estas relaciones que existen entre conjuntos, necesitamos modelar ciertas operaciones:
- Unión: La operación más simple, es la que dados dos conjuntos se queda con todos los elementos que pertenezcan a uno, al otro o a ambos.
- Intersección: Una opración que dados dos conjuntos, resulta en aquellos que pertenecen a ambos.
- Diferencia: Dados los conjuntos A y B, la diferencia A - B serán los elementos de A que no pertenecen a B.
- Complemento: Dados los conjunto A y B, el complemento de A en B serán los elementos de B que no pertenecen a A.
- Diferencia simétrica: La diferencia simétrica entre A y B serán los elementos de A, y los elementos de B, que no forman parte del otro conjunto.
- Producto cartesiano: El producto cartesiano de A y B es un conjunto de pares donde se combinan todos los elementos de A con todos los elementos de B.
- Conjunto potencia: Es aquel formado por todos los posibles subconjuntos de un conjunto dado -desde el conjunto vacío hasta el que contiene todos los elementos, inclusive-. Nótese que es un conjunto de conjuntos.
Se pide implementar una solución que permita realizar todas las operaciones y verificar las relaciones establecidas en el apartado anterior. Para ello deberás emplear los conceptos de colecciones, igualdad, comparación y genéricos (Generics).
Aquí un ejemplo de cómo debería funcionar:
Conjunto<Integer> conjuntoA = new Conjunto<Integer>();
conjuntoA.agregar(1);
conjuntoA.agregar(2);
conjuntoA.agregar(3);
Conjunto<Integer> conjuntoB = new Conjunto<Integer>();
conjuntoA.agregar(3);
conjuntoB.agregar(4);
Conjunto<Integer> conjuntoC = conjuntoA.union(conjuntoB);
// conjuntoC debe contener los elementos {1, 2, 3, 4}
Y así con cada operación y relación.
Se otorga la interfaz de la clase Conjunto
, la cual sirve para implementar las operaciones necesarias. También será necesaria la clase Par
, la cual servirá para implementar la funcionalidad productoCartesiano(Conjunto<S>):Conjunto<Par<T,S>>
.
También se te proveerá un test (dentro de la clase ConjuntoTests
) a modo de testigo, probando el caso proporcionado como ejemplo líneas más arriba. Idealmente deberías hacer crecer esas pruebas, o agregar las tuyas propias para asegurarte de que tu solución es correcta.
Muchas de las operaciones pueden resolverse en función de otras operaciones, simplemente hay que pensarlas un poco más.
Nuestro consejo es que intentes mantener los métodos tan breves como sea posible, ya que todos los métodos pueden implementarse en unas pocas líneas (cuando no son una sóla línea).
Nota: Hay APIs que pueden ayudarte a resolver el problema. Desalentamos el uso de cualquier tipo de jar externo, dado que el objetivo de este ejercicio es el aprendizaje y la familiaridad con las colecciones en Java. Si aún así querés utilizarlas, consultanos sobre cómo hacer para que la corrección automática no falle.
Este trabajo tendrá una nota normalizada en 10.0 puntos, los cuales se componen según el siguiente detalle:
Concepto | Puntos totales | Porcentaje sobre el total |
---|---|---|
Funcionalidad | 8.0 | 80 % |
Estilo | 2.0 | 20 % |
Total | 10.0 | 100 % |
Por lo tanto, se te evaluará tanto la funcionalidad como la correctitud de estilo (tabulación, espacios, nombres, etcétera). Entre los criterios de estilo, esta vez deberás agregar la documentación a los todos los métodos del proyecto.
- Recordá no cambiar la firma de los métodos proporcionados por la cátedra.
- Podés hacer tantos tests como consideres necesarios, pero los mismos no se utilizarán para evaluar tu código.
- Recordá que podés enviar la tarea a corrección tantas veces como quieras, dentro del período de vigencia de la misma.