1

我在 java中寻找与*php 的 array_multisort*等效的东西。

//array 1
ar1 = array(10, 100, 100, 0);
//array 2
ar2 = array(1, 3, 2, 4);
//calling the function
//this will sort the array at first based one the first array and then based on the    
//second array so these two array are related
array_multisort(ar1, ar2);


//resultant 1st array
array(4) {
[0]=> int(0)
[1]=> int(10)
[2]=> int(100)
[3]=> int(100)  
}

//resultant 2nd array
//this array has been sorted based on the first array at first

array(4) {
[0]=> int(4) // this is associative element of 0 in the first array 
[1]=> int(1) //this is associative element of 10 in the first array 
[2]=> int(2) //this is associative element of  1st 100 from the last in the first array 
             //as there are two 100's , and last one's associative value in the second
             //array is smaller it will come first   
[3]=> int(3)
}

我如何使用内置的东西来实现这个结果,我知道如何使用自定义代码来实现它。

注意*请访问这个链接在回答问题之前,因为这解释了该功能应该如何工作*

4

5 回答 5

4

这有点复杂,没有 Java 标准 API 就无法完成。因此,我回收了一个快速排序实现并使其适用于多个数组。基本上,当元素被快速排序的分区交换时,它会交换元素。

干得好:

 /**
   * Multi-sorts the given arrays with the quicksort algorithm. It assumes that
   * all arrays have the same sizes and it sorts on the first dimension of these
   * arrays. If the given arrays are null or empty, it will do nothing, if just
   * a single array was passed it will sort it via {@link Arrays} sort;
   */
  public static void multiQuickSort(int[]... arrays) {
    multiQuickSort(0, arrays);
  }

  /**
   * Multi-sorts the given arrays with the quicksort algorithm. It assumes that
   * all arrays have the same sizes and it sorts on the given dimension index
   * (starts with 0) of these arrays. If the given arrays are null or empty, it
   * will do nothing, if just a single array was passed it will sort it via
   * {@link Arrays} sort;
   */
  public static void multiQuickSort(int sortDimension, int[]... arrays) {
    // check if the lengths are equal, break if everything is empty
    if (arrays == null || arrays.length == 0) {
      return;
    }
    // if the array only has a single dimension, sort it and return
    if (arrays.length == 1) {
      Arrays.sort(arrays[0]);
      return;
    }
    // also return if the sort dimension is not in our array range
    if (sortDimension < 0 || sortDimension >= arrays.length) {
      return;
    }
    // check sizes
    int firstArrayLength = arrays[0].length;
    for (int i = 1; i < arrays.length; i++) {
      if (arrays[i] == null || firstArrayLength != arrays[i].length)
        return;
    }

    multiQuickSort(arrays, 0, firstArrayLength, sortDimension);
  }

  /**
   * Internal multi quicksort, doing the real algorithm.
   */
  private static void multiQuickSort(int[][] a, int offset, int length,
      int indexToSort) {
    if (offset < length) {
      int pivot = multiPartition(a, offset, length, indexToSort);
      multiQuickSort(a, offset, pivot, indexToSort);
      multiQuickSort(a, pivot + 1, length, indexToSort);
    }
  }

  /**
   * Partitions the given array in-place and uses the end element as pivot,
   * everything less than the pivot will be placed left and everything greater
   * will be placed right of the pivot. It returns the index of the pivot
   * element after partitioning. This is a multi way partitioning algorithm, you
   * have to provide a partition array index to know which is the array that
   * needs to be partitioned. The swap operations are applied on the other
   * elements as well.
   */
  private static int multiPartition(int[][] array, int start, int end,
      int partitionArrayIndex) {
    final int ending = end - 1;
    final int x = array[partitionArrayIndex][ending];
    int i = start - 1;
    for (int j = start; j < ending; j++) {
      if (array[partitionArrayIndex][j] <= x) {
        i++;
        for (int arrayIndex = 0; arrayIndex < array.length; arrayIndex++) {
          swap(array[arrayIndex], i, j);
        }
      }
    }
    i++;
    for (int arrayIndex = 0; arrayIndex < array.length; arrayIndex++) {
      swap(array[arrayIndex], i, ending);
    }

    return i;
  }
 /**
   * Swaps the given indices x with y in the array.
   */
  public static void swap(int[] array, int x, int y) {
    int tmpIndex = array[x];
    array[x] = array[y];
    array[y] = tmpIndex;
  }

做了一个小测试用例来测试你对问题的输入:

@Test
  public void testMultiQuickSort() {
    int[] first = new int[] { 10, 100, 100, 0 };
    int[] second = new int[] { 1, 3, 2, 4 };
    int[] resFirst = new int[] { 0, 10, 100, 100 };
    int[] resSecond = new int[] { 4, 1, 2, 3 };

    ArrayUtils.multiQuickSort(first, second);

    for (int i = 0; i < first.length; i++) {
      assertEquals(resFirst[i], first[i]);
      assertEquals(resSecond[i], second[i]);
    }
  }

似乎工作;)

顺便说一句,如果您需要它用于任意对象类型,请发表评论。

于 2012-08-27T13:31:23.610 回答
2

多维数组只是数组的数组,因此遍历各个数组并对它们进行排序:

int[][] marr = // your multi-dimensional array here
for (int[] arr : marr) {
    Arrays.sort(arr);
}

而且,如果出于任何可能的原因,您只想对第二维中的第一个数组进行排序,则可以这样做:

Arrays.sort(marr[0]);

啊,现在我明白你想要什么了。如果您的元素(至少是第一个数组的元素)是唯一的,则可以通过 SortedMap 进行操作:

if(arr1.length!=arr2.length)throw new IllegalArgumentException();
SortedMap<Integer,Integer> map = new TreeMap<Integer, Integer>();
for (int i = 0; i < arr1.length; i++) {
    map.put(arr1[i],arr2[i]);
}
int ct = 0;
for (Entry<Integer, Integer> entry : map.entrySet()) {
    arr1[ct]=entry.getKey();arr2[ct]=entry.getValue();
    ct++;
}
于 2012-08-27T11:55:35.073 回答
0

看起来 Java 中没有为此目的的任何内置库函数/类。如果您也像我一样面临这个问题,那么到目前为止,Thomas关于自定义代码的回答可以帮助您。

于 2012-09-06T15:09:58.433 回答
-1

实现比较器或使用算法冒泡排序

Arrays.sort(stringArray); it will sort only one array
于 2012-08-27T11:13:12.240 回答
-3

也许下面的代码会对你有所帮助。

你应该使用Arrays.sort()

例子:

import java.util.Arrays;

String [] stringArray = {"ab", "aB", "c", "0", "2", "1Ad", "a10"};

//order Ascending
Arrays.sort(stringArray);

//Descending
Arrays.sort(stringArray, Collections.reverseOrder());
于 2012-08-27T11:28:04.007 回答