基于一行数据对二维阵列进行排序

时间:2012-12-12 13:36:38

标签: java arrays

我不确定这个标题是否正确地表明了我想要问的问题。让我们说我有一个二维int数组如下:

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

现在我想按升序排序第一行,第二行中的数据必须在排序后在同一列中,即排序后,数组应如下所示:

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

这样做的正确方法是什么?

6 个答案:

答案 0 :(得分: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}]

答案 1 :(得分:3)

可以通过实现自己的排序算法并在第二行中移动值来完成。

您可能拥有一系列Obejcts。每个对象都将保留值。然后实现自定义比较器并使用sort函数。

我还有一个想法:重新排序数组(如果可以的话)。然后将对保存在一个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]);
        }
});

答案 2 :(得分:1)

简单的方法是创建一个保存对的Pair对象,并使用自定义比较器对Pairs集合进行排序,该比较器仅比较一对的第一项。

如果需要,您始终可以将对转换回2D数组。

这可能不是最有效的方法,但对于大多数用例来说应该足够好。

答案 3 :(得分:0)

如果第一行的所有元素都是唯一且非空的,则可以在排序之前填充第一行元素指向其第二行对应元素的地图。排序完第一行后,您可以使用地图查找第一行(已排序)行的第二行的相应元素。

答案 4 :(得分: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]))};

答案 5 :(得分:0)

我从http://www.algolist.net/Algorithms/Sorting/Quicksort复制粘贴的qSort并稍作修改

    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;
    }
}

此程序打印

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

这可能看起来很长,但通常算法效率至关重要,而这个解决方案似乎是最快的