2012-12-12 197 views
3

我不確定標題是否正確地表明瞭我想要問的內容。比方說,我有如下二維int數組:基於一行數據對二維數組進行排序

int[][] x={{1,7,6},{2,4,8}}; 

現在我想按升序排列的第一行進行排序和數據於第2行必須在排序後的同一列,即後排序,陣列應該是這樣的:

x={{1,6,7},{2,8,4}} 

什麼是正確的方法來做到這一點?

+0

您是否只有兩行數據?或者你可以有N行?如果有N行,您可以將您要排序的行拖入原始索引的值對列表中,按值排序,然後爲每行創建一個新數組,並通過索引提取原始值並替換。 – Charlie

回答

3

這可以通過實現自己的排序例程來完成,但更好的方法是重構。

嘗試將數據封裝爲數組對,每對數組包含在它自己的對象中。然後,您可以對第一個值進行排序並訪問任一值。

class Pair<T extends Comparable<T>> implements Comparable<Pair<T>> { 
    final T a; 
    final T b; 

    public Pair (T a, T b) { 
    this.a = a; 
    this.b = b; 
    } 

    @Override 
    public int compareTo(Pair<T> o) { 
    // Comparison on 'a' only. 
    return a.compareTo(o.a); 
    } 

    @Override 
    public String toString() { 
    return "{" + a + "," + b + "}"; 
    } 
} 

public static void main(String args[]) { 
    Pair[] pairs = { 
    new Pair(1,2), 
    new Pair(7,4), 
    new Pair(6,8), 
    }; 
    System.out.println("Before: "+Arrays.toString(pairs)); 
    Arrays.sort(pairs); 
    System.out.println("After: "+Arrays.toString(pairs)); 
} 

打印

Before: [{1,2}, {7,4}, {6,8}] 
After: [{1,2}, {6,8}, {7,4}] 
+0

這個aproche並不好,因爲你必須打包許多不需要的對象。並通過創建新類來增加complecity到解決方案。 –

+0

@AleksanderGralak - 另一種方法是編寫自己的排序算法。你的選擇。 – OldCurmudgeon

+1

沒有。您可以使用我的解決方案。這是其中一個答案。沒有新的類,沒有新的對象。抱歉有一個新對象:比較器。而且你還有陣列效率。 –

1

最簡單的方法是創建一個Pair對象持有的對,對的集合與定製的比較,只有比較一對中的第一項進行排序。

如果需要,您可以隨時將對變換回二維數組。

這可能不是最有效的方式,但對於大多數使用情況應該足夠好。

3

可以通過實現自己的排序算法並將值移動到第二行來完成。你可能有一個Obejcts數組。每個對象將保持值。然後實現您的自定義比較器並使用排序功能。

我還有一個想法:重新排列數組(如果可以的話)。然後將對保存在一個int []表中。而外部表是INT表一conatiner:

int [][] a = {{2,5},{1,4},{3,6}}; 
Arrays.sort(a, new Comparator<int[]>() { 
     @Override 
     public int compare(int[] p_o1, int[] p_o2) { 
      return Integer.valueOf(p_o1[0]).compareTo(p_o2[0]); 
     } 
}); 
+0

非常適合我的選擇。 – OldCurmudgeon

+0

謝謝。你的想法是我的第一個想法。但是後來我認爲沒有太多的編碼就一定有辦法做到這一點。 –

0

如果所有的第一行的元素是獨一無二的,非空,你可以在排序前,填充一個地圖,第一行元素指向其第二排同行。在對第一行進行排序之後,可以使用該映射查找第二行的第一個(排序的)行的相應元素。

+0

這根本沒有效率。但它會起作用;) –

0

你基本上在做一個Map,爲什麼不使用Map實現來幫助你?

TreeMap實現SortedMap,這樣一個簡單的解決辦法是將所有的映射值裏面:

SortedMap<Integer, Integer> map = new TreeMap<Integer, Integer>(); 
map.put(1, 2); 
map.put(7, 4); 
map.put(6, 8); 

// You can iterate over map now, it'll be already sorted 
for(Map.Entry<Integer, Integer> entry: map.entrySet()) 
{ 
    System.out.println(entry.getKey()+" : "+entry.getValue()); 
} 

// This is not really necessary 
Integer[][] x = {map.keySet().toArray(new Integer[0]), map.values().toArray(new Integer[0])}; 

// If you have Apache Commons you can: 
int[][] y = {ArrayUtils.toPrimitive(map.keySet().toArray(new Integer[0])), ArrayUtils.toPrimitive(map.values().toArray(new Integer[0]))}; 
0

我複製從http://www.algolist.net/Algorithms/Sorting/Quicksort,並稍加修改

public static void main(String[] args) throws Exception { 
     int[][] x = { { 1, 7, 6 }, { 2, 4, 8 } }; 
     qsort(x[0], x[1], 0, x[0].length - 1); 
     System.out.println(Arrays.deepToString(x)); 
    } 

    static void qsort(int[] x0, int[] x1, int left, int right) { 
     int index = partition(x0, x1, left, right); 
     if (left < index - 1) 
      qsort(x0, x1, left, index - 1); 
     if (index < right) 
      qsort(x0, x1, index, right); 
    } 

    static int partition(int[] x0, int[] x1, int left, int right) { 
     int i = left, j = right; 
     int tmp; 
     int pivot = x0[(left + right)/2]; 
     while (i <= j) { 
      while (x0[i] < pivot) 
       i++; 
      while (x0[j] > pivot) 
       j--; 
      if (i <= j) { 
       tmp = x0[i]; 
       x0[i] = x0[j]; 
       x0[j] = tmp; 

       // swap x1 too 
       tmp = x1[i]; 
       x1[i] = x1[j]; 
       x1[j] = tmp; 

       i++; 
       j--; 
      } 
     } 
     return i; 
    } 
} 

這個程序打印粘貼的qsort

[[1, 6, 7], [2, 8, 4]] 

這可能看起來很長,但通常對於算法來說效率非常關鍵,而且這種解決方案似乎是最快的

相關問題