2012-03-29 19 views
35

Sto provando a "combinare" due liste di array, producendo una nuova lista di array che contiene tutti i numeri nelle due liste di array combinate, ma senza elementi duplicati e dovrebbero essere in ordine. Ho trovato questo codice qui sotto. Lo percorro e ha senso per me, ma non sono sicuro se posso usare < o> per confrontare ottenere (i) nelle liste di array. Sto aggiungendo tutti gli elementi di array1 nel plusArray. Quindi sto passando attraverso plusArray e confrontandolo con array2 per vedere se esiste uno qualsiasi degli elementi di array2 all'interno di plusArray. Se lo fanno, non sto facendo nulla, ma se non lo fanno, sto cercando di aggiungerlo nella sua posizione corretta. Forse il mio nested for loop è stato usato in modo errato? Nota: le liste di array sono preselezionate dall'utente in ordine crescente.Unione di due elenchi di array in una nuova lista di array, senza duplicati e in ordine, in Java

 ArrayList<Integer> plusArray = new ArrayList<Integer>(); 
for(int i = 0; i < array1.size(); i++){ 
    plusArray.add(array1.get(i)); 
} 

for(int i = 0; i < plusArray.size(); i++){ 
    for(int j = 0; j < array2.size(); j++){ 

    if(array2.get(j) < plusArray.get(i)){ 
     plusArray.add(i,array2.get(j)); 
    } 
    else if(plusArray.get(i).equals(array2.get(j))){ 
     ; 
    } 
    else if(array2.get(j) > plusArray.get(i)){ 
     plusArray.add(i, array2.get(j)); 
    } 

} 

AGGIORNAMENTO: Non ottengo più l'eccezione qui sotto. Invece sembra che il programma funzioni per sempre. Ho cambiato la posizione in cui aggiungere gli elementi nelle condizioni < e>. /// Ecco l'eccezione che ho quando le mie liste di array sono: IntSet 1: {1} 2 IntSet 2: {1} 3 4

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
at java.util.Arrays.copyOf(Unknown Source) 
at java.util.Arrays.copyOf(Unknown Source) 
at java.util.ArrayList.grow(Unknown Source) 
at java.util.ArrayList.ensureCapacityInternal(Unknown Source) 
at java.util.ArrayList.add(Unknown Source) 
at IntSet.plus(IntSet.java:92) 
at IntSetDriver.main(IntSetDriver.java:61) 
+0

Si prega di inviare l'eccezione che si ottiene. –

risposta

23

al posto del codice che hai scritto, è possibile utilizzare ArrayList.addAll() per unire le liste, Collections.sort() di risolvere e, infine traversata del ArrayList risultante per rimuovere i duplicati. La complessità aggregata è quindi O(n)+O(n*log(n))+O(n) che equivale a O(n*log(n)).

+0

Penso che questa risposta sia un po 'errata in quanto l'intero algoritmo non finisce in O (n). L'ordinamento può richiedere O (nlogn). Inoltre, anche se Traversal è O (n), la cancellazione da ArrayList può richiedere O (n) in quanto richiede la copia di (al massimo) n elemento. – Kazuki

4

Forse la mia cicli for innestati essere usato in modo errato?

Suggerimento: i cicli nidificati non funzioneranno per questo problema. Neanche un ciclo for semplice funzionerà.

È necessario visualizzare il problema.

Scrivi due elenchi ordinati su un pezzo di carta e, utilizzando due dita per puntare gli elementi delle rispettive liste, attraversali mentre fai l'unione nella tua testa. Quindi traduci il tuo processo decisionale mentale in un algoritmo e poi codice.

La soluzione ottimale fa un singolo passaggio attraverso i due elenchi.

+0

quindi dire un ciclo while o fare un ciclo? non sono quelli uguali a quelli di loop in un formato diverso – Milwaukoholic

+0

ok ... forse lo guarderò male domani e le cose arriveranno più chiaramente. – Milwaukoholic

+0

Altri suggerimenti? Continuo a tornare alla mia soluzione originale che pensavo avrebbe funzionato – Milwaukoholic

2

Il secondo ciclo dovrebbe avere j ++ invece che i ++

+0

L'ho risolto e inserito nella nuova eccezione – Milwaukoholic

2

Non sono sicuro del motivo per cui il codice corrente non funziona (qual è l'eccezione che ottieni?), Ma vorrei sottolineare che questo approccio esegue O (N al quadrato). Considerate preselezione gli array di ingresso (se non sono definite per essere pre-ordinato) e si fondono le matrici ordinate:

http://www.algolist.net/Algorithms/Merge/Sorted_arrays

ordinamento è generalmente O (N log N) e l'unione è O (m + n).

+0

Non sono sicuro che dovrei usare questo approccio perché non l'ho ancora imparato in classe. Immagino che non sarebbe male però? – Milwaukoholic

+0

Se l'istruttore ha insegnato un approccio specifico, probabilmente vorrai almeno implementare ciò che ha mostrato. È molto importante, tuttavia, avere familiarità con il concetto di big-O e le prestazioni relative di diversi algoritmi. Se hai tempo, implementa anche questo approccio e confronta le prestazioni con input abbastanza grandi. –

+0

Beh, non ci ha davvero insegnato come farlo. Ci hanno appena insegnato il codice e dobbiamo implementare ciò che sappiamo per farlo. Idk – Milwaukoholic

1

tuo annidati ciclo

for(int j = 0; j < array2.size(); i++){ 

è infinito come j sarà sempre uguale a zero, d'altra parte, i sarà aumentato a piacimento in questo ciclo. Ottiene OutOfBoundaryException quando i è maggiore di plusArray.size()

+0

sì fisso e inserisce la nuova eccezione – Milwaukoholic

+0

ArrayList.add (x) aggiunge x alla fine dell'elenco, quindi non stavi ordinando ArrayList, tuttavia il tuo ciclo ha bisogno del plusArray ordinato, giusto? – Southeast

+0

Collezioni API Java e ArrayList: http://docs.oracle.com/javase/1.5.0/docs/api/ – Southeast

11

Aggiungi ArrayList1, ArrayList2 e produce un Arraylist ArrayList3 singolo. Ora convertirlo in

Set Unique_set = new HashSet(Arraylist3); 

nel set unico otterrete gli elementi unici.
Nota

ArrayList permette di duplicare i valori. Set non consente la duplicazione dei valori. Spero che il tuo problema risolva.

+0

Non ho appreso HashSets o l'addAll() o la roba O() ... – Milwaukoholic

+0

Provate ad imparare le Collezioni Java per risolvere la maggior parte delle vostre esigenze. – special

56

rimuovere i duplicati In primo luogo:

arrayList1.removeAll(arrayList2); 

quindi unire due arrayList:

arrayList1.addAll(arrayList2); 

Infine, ordinare il vostro arrayList se lo si desidera:

collections.sort(arrayList1); 

Nel caso in cui non si vuole per apportare modifiche all'elenco esistente, innanzitutto creare i rispettivi elenchi di backup:

arrayList1Backup = new ArrayList(arrayList1); 
+0

se qualcuno trova che questo non funziona, si noti che gli oggetti nell'elenco dovrebbero sovrascrivere il metodo equals perché questo funzioni, perché -> http://stackoverflow.com/a/35960394/441902 – cherit

10
List<String> listA = new ArrayList<String>(); 

    listA.add("A"); 
    listA.add("B"); 

List<String> listB = new ArrayList<String>(); 

    listB.add("B"); 
    listB.add("C"); 

Set<String> newSet = new HashSet<String>(listA); 

    newSet.addAll(listB); 
List<String> newList = new ArrayList<String>(newSet); 

System.out.println("New List :"+newList); 

ti dà Nuova lista: [A, B, C]

3

Aggiungi elementi in primo arraylist

ArrayList<String> firstArrayList = new ArrayList<String>(); 

firstArrayList.add("A"); 
firstArrayList.add("B"); 
firstArrayList.add("C"); 
firstArrayList.add("D"); 
firstArrayList.add("E"); 

aggiungere elementi in seconda arraylist

ArrayList<String> secondArrayList = new ArrayList<String>(); 

secondArrayList.add("B"); 
secondArrayList.add("D"); 
secondArrayList.add("F"); 
secondArrayList.add("G"); 

Aggiungere elementi prima di ArrayList in seconda arraylist

secondArrayList.addAll(firstArrayList); 

assegnare nuovi combinare arraylist e aggiungere tutti gli elementi da entrambi i ArrayLists

ArrayList<String> comboArrayList = new ArrayList<String>(firstArrayList); 
comboArrayList.addAll(secondArrayList); 

Assegnare nuovo Set per rimuovere voci duplicate da arraylist

Set<String> setList = new LinkedHashSet<String>(comboArrayList); 
comboArrayList.clear(); 
comboArrayList.addAll(setList); 

Ordinamento arraylist

Collections.sort(comboArrayList); 

uscita

A 
B 
C 
D 
E 
F 
G 
-1

Non è necessario a questo handcode. La definizione del problema è precisamente il comportamento di Apache Commons CollectionUtils#collate. È anche sovraccarico per diversi ordinamenti e consentendo duplicati.

+0

forse questo dovrebbe essere un commento invece di una risposta ... – jpganz18

+0

La risposta superiore ha esattamente la stessa forma di questa: "non scrivere da solo, qui ci sono oggetti che lo faranno per te". Ho modificato il mio fraseggio. – Noumenon

0
**Add elements in Final arraylist,** 
**This will Help you sure** 

import java.util.ArrayList; 
import java.util.List; 

public class NonDuplicateList { 

public static void main(String[] args) { 

    List<String> l1 = new ArrayList<String>(); 
    l1.add("1");l1.add("2");l1.add("3");l1.add("4");l1.add("5");l1.add("6"); 
    List<String> l2 = new ArrayList<String>(); 
    l2.add("1");l2.add("7");l2.add("8");l2.add("9");l2.add("10");l2.add("3"); 
    List<String> l3 = new ArrayList<String>(); 
    l3.addAll(l1); 
    l3.addAll(l2); 
    for (int i = 0; i < l3.size(); i++) { 
     for (int j=i+1; j < l3.size(); j++) { 
      if(l3.get(i) == l3.get(j)) { 
       l3.remove(j); 
      } 
     } 
    } 
    System.out.println(l3); 
} 

}

uscita: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

+0

Non scaricare semplicemente il codice. Si prega di spiegare perché questa soluzione funziona. – user2004685

3

Java 8 Stream API può essere utilizzato per lo scopo,

ArrayList<String> list1 = new ArrayList<>(); 

list1.add("A"); 
list1.add("B"); 
list1.add("A"); 
list1.add("D"); 
list1.add("G"); 

ArrayList<String> list2 = new ArrayList<>(); 

list2.add("B"); 
list2.add("D"); 
list2.add("E"); 
list2.add("G"); 

List<String> noDup = Stream.concat(list1.stream(), list2.stream()) 
        .distinct() 
        .collect(Collectors.toList()); 
noDup.forEach(System.out::println); 

En passant, non dovrebbe essere forgetten che distinct() fa uso di hashCode().

0

Ho capito che non si desidera utilizzare le funzioni integrate per unire o rimuovere i duplicati da ArrayList. Il tuo primo codice è in esecuzione per sempre perché la condizione esterna per il ciclo è 'Sempre vero'. Dato che si stanno aggiungendo elementi a plusArray, la dimensione di plusArray aumenta con ogni aggiunta e quindi 'i' è sempre inferiore. Di conseguenza, la condizione non fallisce mai e il programma funziona per sempre. Suggerimento: provare prima a unire l'elenco e quindi dall'elenco unito rimuovere gli elementi duplicati. :)

Problemi correlati