2010-08-28 34 views
31

Quiero tener operaciones de unión, intersección, diferencia e inversión en Java.Cómo hacer unión, intersección, diferencia e invertir datos en java

Primero tengo 2 casos de ArrayList<Integer>

a = [0,2,4,5,6,8,10] 
b = [5,6,7,8,9,10] 

una unión B debería devolver c = [0,2,3,4,5,6,7,8,9,10]

un intersecan b debe devolver c = [5,8,10]

un defference b debe devolver c = [0,2,3,4]

inversa a = [10,8,6,5,4,2,0]

Algo como esto.

¿Cómo implementar ese método en Java?


actualización: Tengo que empezar con esta plantilla:

package IntSet; 
import java.util.ArrayList; 
import java.util.Collection; 


public class IntSet { 

private ArrayList<Integer> intset; 

public IntSet(){ 
    intset = new ArrayList<Integer>(); 
} 

public void insert(int x){ 
    intset.add(x); 
} 

public void remove(int x){ 
    //implement here 
    intset.indexOf(x); 
} 

public boolean member(int x){ 
    //implement here 
    return true; 
} 

public IntSet intersect(IntSet a){ 
    //implement here 
    return a; 
} 

public IntSet union(IntSet a){ 
    //implement here 
    return a; 
} 

public IntSet difference(IntSet a){ 
    //implement here 
    IntSet b = new IntSet(); 
    return b; 
} 
+1

Una vez más, estamos hablando acerca de las funciones de ajuste, pero utilizar listas. Entonces su función de inserción ya está equivocada: no está probando duplicados. – Landei

Respuesta

30
//Union 
List<Integer> c = new ArrayList<Integer>(a.size() + b.size()); 
addNoDups(c,a); 
addNoDups(c,b); 

private void addNoDups(List<Integer> toAddTo,List<Integer> iterateOver) { 
    for(Integer num:iterateOver){ 
     if(toAddTo.indexOf(num) == -1) { 
      toAddTo.add(num); 
     } 
    } 
} 

//intersection 
List<Integer> c = new ArrayList<Integer> (a.size() > b.size() ?a.size():b.size()); 
c.addAll(a); 
c.retainAll(b); 

//difference a-b 
List<Integer> c = new ArrayList<Integer> (a.size()); 
c.addAll(a); 
c.removeAll(b); 
+2

+1 para una respuesta concisa. Aunque creo que podrías haber usado Hashset en lugar de ArrayList para llevar a casa el punto. – Hari

+0

+1 Pero ... Este enfoque puede reservar más espacio, luego se requiere para el resultado 'List c'. Tal vez, sería mejor no reservar ese espacio durante el tiempo de creación del 'nuevo ArrayList' en absoluto? –

+0

@DmytroDzyubak La complejidad de todos los métodos es cuadrática, lo que suele ser mucho peor que utilizar un espacio extraño. A veces puede ser aceptable, pero la solución al menos lo menciona claramente. – maaartinus

59

En primer lugar, las operaciones que describes (excepto inversa) son operaciones establecidas, no enumera las operaciones, a fin de utilizar HashSet o (si necesita un pedido) TreeSet.

Set<Integer> a = new TreeSet<Integer>(Arrays.asList(new Integer[]{0,2,4,5,6,8,10})); 
    Set<Integer> b = new TreeSet<Integer>(Arrays.asList(new Integer[]{5,6,7,8,9,10})); 

    //union 
    Set<Integer> c = new TreeSet<Integer>(a); 
    c.addAll(b); 
    System.out.println(c); 

    //intersection 
    Set<Integer> d = new TreeSet<Integer>(a); 
    d.retainAll(b); 
    System.out.println(d); 

    //difference 
    Set<Integer> e = new TreeSet<Integer>(a); 
    e.removeAll(b); 
    System.out.println(e); 

    //reverse 
    List<Integer> list = new ArrayList<Integer>(a); 
    java.util.Collections.reverse(list); 
    System.out.println(list); 
+5

Si declaras 'a' y' b' como 'NavigableSet', entonces puedes invertir su orden usando el método' descendingSet() '. Para un 'conjunto' general, no hay noción de orden. – Natix

+0

Buena respuesta, aunque la parte inversa no tiene sentido. Se originó en la cabeza de OP, pero no tienes que seguir esto. O bien, podría proporcionar un conjunto con el comparador opuesto. – Vlasec

8

Muchas de las respuestas que dicen usar bibliotecas que va a hacer el trabajo por usted. Si bien esta es la solución correcta para el mundo real, tenga en cuenta que está haciendo la tarea, y su maestro probablemente quiera que comprenda cómo se escriben las funciones, no solo cómo encontrar las bibliotecas para que hagan el trabajo por usted.

Dicho esto, tiene un buen comienzo con el código que ha mostrado. Tomemos el problema paso a paso.

En primer lugar, ¿sabe dónde se encuentra la documentación de Java? http://download.oracle.com/javase/1.4.2/docs/api/ esto es crítico, ya que así es como descubres qué funciones hacen qué. Aquí está el enlace a Java 1.4. No noté qué versión estás usando, pero Java es compatible con versiones anteriores, así que esto debería ser suficiente.

En los documentos, busque la entrada ArrayList.

Ahora que tenemos los documentos API, tenemos que desglosar su pregunta. has publicado el código, así que lo abordaré función por función.

insertar(): ¿tiene que tener una lista ordenada, o no importa? ¿O tiene la garantía de que se le proporcionarán los valores en orden? ¿Ya aprendiste los algoritmos de clasificación?

remove(): esta función no funciona. Eche un vistazo a la API ArrayList y vea cómo eliminar un elemento de la lista. Usa ese método.

member(): su método de miembro no funciona. Debe verificar cada entrada de la lista y determinar si el miembro actual coincide con el argumento de la función. ¿Has aprendido sobre bucles?

intersect(): bien, dígame en inglés qué intersect se supone que debe hacer.No use la descripción del maestro si puede ayudarlo - use sus propias palabras (tenga en cuenta que este es un ejercicio para que el OP aprenda a programar, por favor no lo conteste)

diferencia(): de nuevo, dime en inglés qué se supone que debe hacer.

reverse(): de nuevo, dame la descripción en inglés de lo que se supone que debe hacer.

Una vez que tenga las descripciones en inglés, describa un algoritmo que pueda hacer el trabajo. no lo escriba en Java todavía. simplemente escriba un algoritmo, en inglés, que describa cómo haría el trabajo de forma manual, con lápiz y papel.

En este punto, intente convertir el algoritmo a código Java.

18

Si está utilizando Conjuntos (como debería, para todos aquellos, excepto en reversa, son operaciones de Configuración), Guava proporciona estas operaciones en su clase Sets.

Set<Integer> union = Sets.union(set1, set2); 
Set<Integer> intersection = Sets.intersection(set1, set2); 
Set<Integer> difference = Sets.difference(set1, set2); 

Todos estos devuelven vistas no modificables, respaldadas por los Conjuntos originales.

Ver Guava Explained ->Collection Utilities ->Sets

Si las listas son lo que tiene, puede convertirlos a un conjunto utilizando el constructor de copia presente en todas las colecciones estándar:

List<X> list = new ArrayList<>(); 
// fill up list here 
Set<X> set = new HashSet<>(list); 
0

Este fragmento se encuentra la unión de dos colecciones utilizando apache commons CollectionUtils.union método

Collection<String> totalFriends = CollectionUtils.union(yourFriends, myFriends); 
+0

esto fue preguntado hace seis años – sbowde4

1

Lo dejo aquí. Hay una nueva forma con java-8 y streams

List<Integer> listA = Arrays.asList(0, 2, 4, 5, 6, 8, 10); 
List<Integer> listB = Arrays.asList(5, 6, 7, 8, 9, 10); 

List<Integer> intersection = listA.stream() 
     .filter(listB::contains) 
     .collect(Collectors.toList()); 

List<Integer> union = Stream.concat(listA.stream(), listB.stream()) 
     .distinct().sorted() 
     .collect(Collectors.toList()); 

List<Integer> aDiffB = listA.stream() 
     .filter(i -> !listB.contains(i)) 
     .collect(Collectors.toList()); 

System.out.println(intersection); // [5, 6, 8, 10] 
System.out.println(union); // [0, 2, 4, 5, 6, 7, 8, 9, 10] 
System.out.println(aDiffB); // [0, 2, 4] 
Cuestiones relacionadas