2012-04-05 11 views
5

sortieren Ich habe eine zweidimensionale Arraylist, die doppelten Werte enthält:Wie eine zwei Dimension Arraylist

ArrayList<ArrayList<Double>> data = new ArrayList<ArrayList<Double>>(); 

In Analogie zu klassischen Arrays ich die „cols“ diese Matrix sortieren möchte: I Ich möchte die Elemente mit demselben Index in den Sub-ArrayLists verwenden und sie dann sortieren. Wie das Aufrufen von Collections.sort() für jede Spalte ... Mit Zeilen meine ich die äußere Ebene und die innere Ebene sind Spalten.

Was ist der richtige Weg, dies zu tun? Ich dachte daran, über die Matrix zu iterieren, um sie zu invertieren und dann jede Zeile mit Collections.sort() zu sortieren? aber vielleicht ist es nicht die beste Lösung, weil die Matrix etwa 400 * 7000 ist.

Ich kann keine klassischen Arrays verwenden, da die Größe der Matrix unbekannt ist.

Danke für Hilfe.

+0

Ich nehme an, äußere Ebene stellt Zeilen dar, aber es wäre nett, wenn Sie es in Ihrer Frage angeben könnten. – ahanin

+0

sind die Doppelgänger irgendwelche spezifischen Zahlen oder nur zufällig? Was bedeuten sie? – noMAD

+0

Haben Sie sich spezialisierte Matrixbibliotheken wie [JaMa] (http://math.nist.gov/javanumerics/jama/) angesehen? Wenn einer von ihnen Ihre Anforderungen erfüllt, sparen Sie möglicherweise viel Zeit. – Barend

Antwort

3

etwas tun:

final int COLUMN = 5; 
    Comparator<ArrayList<Double>> myComparator = new Comparator<ArrayList<Double>>() { 
     @Override 
     public int compare(ArrayList<Double> o1, ArrayList<Double> o2) { 
      return o1.get(COLUMN).compareTo(o2.get(COLUMN)); 
     } 
    }; 
    Collections.sort(list, myComparator); 

-Set-Spalte zu, was Spalte Sie Sortierung auf.

Update:

Ja, das wird nicht funktionieren.

Ich mag Ahamins zweiten Vorschlag, um Ihre eigene Liste zu erstellen, die Ihre ursprüngliche Liste umschließt. Sie müssten auch das von get() zurückgegebene Objekt umbrechen, so dass die Variable "WrappedList" die Spaltenwerte enthält und "WrappedList.get (0)" ebenfalls eine Spalte mit Werten zurückgibt. Dann kann die Sortierung funktionieren. Ich frage mich, was die minimalen Methoden sind, die Sie für Collections.sort() implementieren müssen, um auf Ihrer Liste zu arbeiten.

Es wäre wahrscheinlich am einfachsten, jemandes Quicksort einfach zu nehmen und es mit Ihrer Liste arbeiten zu lassen.

Hier eine Implementierung ist: http://www.vogella.de/articles/JavaAlgorithmsQuicksort/article.html

+1

Das OP fragt nicht nach einer bestimmten Spalte, es werden die Spalten unabhängig voneinander sortiert. – trutheality

+0

Mein Verständnis ist, dass er ** alle ** Spalten sortiert haben möchte, also müssen wir die Doppel-Elemente tatsächlich zwischen den Listen verschieben. –

+0

@SarelBotha: Ja Ich möchte jede Spalte unabhängig sortieren, Collections.sort() sollte so oft wie die Anzahl der Spalten (= Die Größe der inneren ArrayLists) aufgerufen werden. – Believer

2

Ich habe zwei verrückte Ideen: Entweder um einen eigenen Sortieralgorithmus zu implementieren, der Ihre invertierte Matrixstruktur kennt, oder Sie schreiben eine Implementierung von Collection, die Ihre Struktur umschließt und die Spalte darstellt, die später als Argument zu Collections.sort(). Mit ArrayList sollte das ziemlich schnell sein.

0

Ich denke, wenn Speicher kein Problem ist, können Sie eine SortedMap in Ihrer ArrayList verwenden. Auf diese Weise müssen Sie sich nicht um das Sortieren der Elemente kümmern.

ArrayList<SortedMap<Double,byte>> data; 
+2

Wie wird das funktionieren? Es würde es nach Zeilen sortieren und das ist nicht das, was er will. – noMAD

+0

Ich glaube nicht, dass zwischen Zeilen und Spalten Klarheit herrscht. Außerdem ist es nur eine logische Anzeige, die nur angezeigt wird, wenn Sie sie durchlaufen. Alles hängt von der verwendeten Traversiertechnik ab. –

0

nicht sicher, ob ich richtig Ihre Q verstanden, aber das wird sortieren alle „Spalten“ (unter der Annahme, äußere Ebene sind Zeilen und innere Ebene sind Spalten):

final ArrayList<ArrayList<Double>> data = new ArrayList<ArrayList<Double>>(); 
    //... 

    final Integer[] rows = new Integer[data.size()]; 
    for(int i=0;i<rows.length;i++) 
     rows[i]=i; 

    int cols = data.get(0).size(); 
    for(int c=0;c<cols;c++) 
    { 
     final int colidx = c; 
     Arrays.sort(rows,new Comparator<Integer>(){ 
      @Override 
      public int compare(Integer arg0, 
        Integer arg1) { 
       return data.get(arg0).get(colidx).compareTo(data.get(arg1).get(colidx));   
      }});  

     for(int i=0;i<rows.length;i++) 
      data.get(i).add(colidx+1,data.get(rows[i]).get(colidx)); 
     for(int i=0;i<rows.length;i++) 
      data.get(i).remove(colidx); 
    } 
3

Also hier ist eine Option, die wie die Inversionsidee ist, aber anstatt das Ganze zu invertieren, baut man eine Spalte nach der anderen, sortiert sie und verwirft sie.

ArrayList<ArrayList<Double>> data = new ArrayList<ArrayList<Double>>(); 

for(int c=0; c<data.get(0).size(); c++) { 
    List<Double> col = new ArrayList<Double>(); 
    for(int r=0; r<data.size(); r++) 
     col.add(data.get(r).get(c)); 

    Collections.sort(col); 

    for(int r=0; r<col.size(); r++) 
     data.get(r).set(c, col.get(r)); 
} 

Ich bezweifle, dass Sie in der Lage sein werden, etwas effizienter zu bekommen, außer vielleicht die Möglichkeit, Ihre eigene Klasse erstellen, die als Liste eine Ansicht einer Spalte der Tabelle.

0

Sie müssen alle Elemente besuchen, um sie auf jeden Fall zu sortieren. Was du also tun könntest ist das.

int temp[] = new temp[col.length]; 
int x = 0; 
while(x < row.length) 
{ 
    for(int i = 0; i<col.length; i++) 
    { 
     temp[i] = mat[x][i]; 
    } 
    sort(temp); 
    for(int i = 0; i<col.length; i++) 
    { 
     mat[x][i] = temp[i]; 
    } 
x++; 
} 

hier die Laufzeit O(n^2logn) sein würde, aber da Sie nur 400 verdoppelt werden Sortieranlagen, die nicht nehmen viel Zeit würde. und da Sie jedes Element in der Matrix mindestens einmal zu besuchen, können Sie nicht gehen unter O(n^2)

2

Hier ist ein Ansatz, um diese Situation der Umwandlung der Daten in ein Objekt-Array. Ändern Sie die Spalte zu dem, was Ihnen gefällt.

final int column = 3; 
ArrayList<ArrayList<Double>> data = new ArrayList<ArrayList<Double>>(); 

// Convert data into an object array 
Object [] temp = data.toArray(); 

Arrays.sort(temp, new Comparator<Object>() { 
    @Override 
    public int compare(Object o1, Object o2) { 
     // Get inner arrays to be compared by type-casting 
     ArrayList<Double> temp1 = (ArrayList<Double>) o1; 
     ArrayList<Double> temp2 = (ArrayList<Double>) o2; 

     // Then compare those inner arrays' indexes 
     return temp1.get(column).compareTo(temp2.get(column)); 
    } 
}); 

// Clear the old one and add the ordered list into 
data.clear(); 

for(Object o: temp) 
{ 
    data.add((ArrayList<Double>) o); 
} 
Verwandte Themen