Java中匹配数组的排序

Java中匹配数组的排序,java,sorting,list,Java,Sorting,List,假设我有两个数组(在Java中) int[]数字;和int[]颜色 数字的每个第i个元素对应于其颜色的第i个元素。 例如,数字={4,2,1} 颜色={0x11,0x24,0x01};表示数字4为颜色0x11,数字2为0x24,以此类推 我想对数字数组进行排序,但仍然保留该数组,以便每个元素在颜色上与其对匹配 例如,数字={1,2,4}; 颜色={0x01,0x24,0x11} 最干净、最简单的方法是什么?阵列有几千个项目,因此最好是到位,但不是必需的。使用Arrays.sort()和自定义比较

假设我有两个数组(在Java中)

int[]数字;和int[]颜色

数字的每个第i个元素对应于其颜色的第i个元素。 例如,数字={4,2,1} 颜色={0x11,0x24,0x01};表示数字4为颜色0x11,数字2为0x24,以此类推

我想对数字数组进行排序,但仍然保留该数组,以便每个元素在颜色上与其对匹配

例如,数字={1,2,4}; 颜色={0x01,0x24,0x11}

最干净、最简单的方法是什么?阵列有几千个项目,因此最好是到位,但不是必需的。使用Arrays.sort()和自定义比较器有意义吗?最好尽可能多地使用库函数


注意:我知道“最佳”解决方案是为这两个元素创建一个类,并使用自定义比较器。这个问题的目的是询问人们编写代码的最快方法。想象一下,在一场编程竞赛中,你不想让所有这些额外的类、比较器的匿名类等等变得更好,忘记Java吧;您将如何用C编写它?

您需要按照颜色数组在数字数组中的相对项对其进行排序。指定一个比较数字的比较器,并将其用作颜色数组的比较。

为什么不引入一个对象来表示数字和颜色,并为此实现一个比较器函数


另外,您真的需要数组吗?为什么不使用从集合派生的东西呢?

看起来最干净的方法是创建一个实现Comparable的自定义属性类。例如:

class Color implements Comparable {
  private int number;
  private int color;

  // (snip ctor, setters, etc.)

  public int getNumber() {
    return number;
  }
  public int getColor() {
    return color;
  }

  public int compareTo(Color other) {
    if (this.getNumber() == other.getNumber) {
      return 0;
    } else if (this.getNumber() > other.getNumber) {
      return 1;
    } else {
      return -1;
    }
  }
}

然后,您可以将排序算法与排序逻辑分离(如果使用列表而不是数组,则可以使用Collections.sort),最重要的是,您不必担心两个数组不同步。

如果您愿意分配一些额外的空间,您可以生成另一个数组,称之为extra,有这样的元素:

extra = [0,1,...,numbers.length-1]
int[] idx = new int[numbers.length];
for( int i = 0 ; i < idx.length; i++ ) idx[i] = i;
final boolean isStableSort = false;
Primitive.sort(idx,
               (i1, i2) -> Double.compare(numbers[i1], numbers[i2]),
               isStableSort);

// numbers[idx[i]] is the sorted number at index i
// colors[idx[i]] is the sorted color at index i
然后,您可以使用Arrays.sort()和自定义比较器对这个额外的数组进行排序(在比较元素i和j时,实际上是比较数字[extra[i]]和数字[extra[j]])。这样,在对额外数组进行排序后,额外[0]将包含最小数字的索引,并且由于数字和颜色没有移动,因此包含相应的颜色。
这不是很好,但它完成了任务,我真的想不出更简单的方法来完成

作为一个侧面的注释,在竞争中我通常发现C++模板对和漂亮的地图是不可缺少的;p> 如果在索引中保留第三个数组,并在该数组上进行排序,使数据保持完整,则可以将sort()与自定义比较器一起使用

Java代码示例:

Integer[] idx = new Integer[numbers.length];
for( int i = 0 ; i < idx.length; i++ ) idx[i] = i;              
Arrays.sort(idx, new Comparator<Integer>() {
    public int compare(Integer i1, Integer i2) {                        
        return Double.compare(numbers[i1], numbers[i2]);
    }                   
});

// numbers[idx[i]] is the sorted number at index i
// colors[idx[i]] is the sorted color at index i
Integer[]idx=新整数[numbers.length];
对于(inti=0;i

请注意,必须使用
Integer
而不是
int
,否则不能使用自定义比较器

我喜欢@tovare的解决方案。创建指针数组:

int ptr[] = { 1, 2, 3 };
然后,当您对数字进行排序时,交换ptr中的值,而不是数字中的值。然后通过ptr阵列进行访问,如

for (int i = 0; i < ptr.length; i++)
{
   printf("%d %d\n", numbers[ptr[i]], colors[ptr[i]]);
}
for(int i=0;i

更新:好吧,看来其他人已经打败了我。我没有XP。

编写自己的排序方法就足够了吗?一个简单的bubblesort可能很快就能编写代码(并且正确)。不需要额外的类或比较器。

一个快速解决方法是将两个阵列与位移位相结合。制作一个长数组,使最高有效32位为数字,最低有效32位为颜色。使用排序方法,然后解包。

在C中最简单的方法是使用bubblesort+双指针。当然,最快的是快速排序+两个指针。当然,第二个指针保持两个数组之间的相关性


我宁愿将存储在两个数组中的值定义为一个结构,并在单个数组中使用该结构。然后对其使用快速排序。您可以通过调用比较函数来编写sort的通用版本,然后可以为每个结构编写比较函数,但您已经知道:)

这是一个使用第三个索引数组的示例。不确定这是否是最好的实现


导入java.util.*

Not sorted No Num Color ---------------- 0 1 80 1 4 52 2 3 0 3 4 254 4 2 255 5 6 255 Sorted by numbers No Num Color ---------------- 0 6 255 1 4 52 2 4 254 3 3 0 4 2 255 5 1 80 Sorted by colors No Num Color ---------------- 0 6 255 1 2 255 2 4 254 3 1 80 4 4 52 5 3 0
公共类排序{
私有静态void打印表(字符串标题,整数[]数字,
整数[]颜色,整数[]排序器){
System.out.println(标题+
“\n没有数字颜色”+
“\n---------------------------”;

对于(int i=0;i使用
@tovare
的积分来获得原始最佳答案

我下面的答案从这个答案中删除了(现在)不必要的通过Maven依赖项的自动装箱:

int[]idx=newint[numbers.length];
对于(inti=0;iDouble.compare(数字[i1],数字[i2]),
(国际体育协会);
//numbers[idx[i]]是索引i处的排序数
//颜色[idx[i]]是索引i处的排序颜色

我猜您希望在尝试避免使用对象数组(这可能会导致痛苦的GC事件)的同时实现性能优化。 不幸的是,没有一个通用的解决方案,我想。 但是,对于数字彼此不同的特定情况,可能只需要创建两个数组

/**
*仅适用于不同数字的数组
*/
私有void排序阵列(int[]数字,int[]颜色){
int[]tmpNumbers=Arrays.copyO
int[] idx = new int[numbers.length];
for( int i = 0 ; i < idx.length; i++ ) idx[i] = i;
final boolean isStableSort = false;
Primitive.sort(idx,
               (i1, i2) -> Double.compare(numbers[i1], numbers[i2]),
               isStableSort);

// numbers[idx[i]] is the sorted number at index i
// colors[idx[i]] is the sorted color at index i
/**
 * work only for array of different numbers
 */
private void sortPairArray(int[] numbers, int[] colors) {
    int[] tmpNumbers = Arrays.copyOf(numbers, numbers.length);
    int[] tmpColors = Arrays.copyOf(colors, colors.length);
    Arrays.sort(numbers);
    for (int i = 0; i < tmpNumbers.length; i++) {
        int number = tmpNumbers[i];
        int index = Arrays.binarySearch(numbers, number); // surely this will be found
        colors[index] = tmpColors[i];
    }
}