用Java对匹配数组进行排序
假设我有两个数组(在Java中),
int []个数字;和int []颜色;
每个数字的第i个元素对应于其第i个颜色元素。
例如,数字= {4,2,1}
颜色= {0x11,0x24,0x01};表示数字4是颜色0x11,数字2是颜色0x24,依此类推。
我想对numbers数组进行排序,但是仍然要对它进行排序,以便每个元素与其颜色配对。
前任。数字= {1,2,4};
颜色= {0x01,0x24,0x11};
什么是最干净,最简单的方法?数组有几千个项目,因此最好放置在适当的位置,但不是必需的。进行Arrays.sort()和自定义比较器是否有意义?最好使用库函数。
注意:我知道"最佳"解决方案是为两个元素创建一个类并使用自定义比较器。这个问题是要问人们最快速的编码方法。想象一下,在参加编程竞赛时,我们不想制作所有这些额外的类,比较器的匿名类等。更好的是,忘记了Java。我们将如何用C编写代码?
解决方案
我们需要按colors数组在numbers数组中的相对项对它们进行排序。指定一个比较数字的比较器,并将其用作颜色数组的比较。
为什么不引入一个表示数字和颜色的对象并为此实现比较器功能呢?
另外,我们是否真的需要一个数组,为什么不使用从Collection派生的东西呢?
看起来最干净的方法是创建一个实现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; } } }
然后,我们可以将排序算法与排序逻辑分开(如果使用List而不是数组,则可以使用Collections.sort),最重要的是,我们不必担心以某种方式使两个数组不同步。
如果我们愿意分配一些额外的空间,则可以生成另一个数组,将其称为额外的数组,其元素如下所示:
extra = [0,1,...,numbers.length-1]
然后,我们可以使用带有自定义比较器的Arrays.sort()对这个额外的数组进行排序(在比较元素i和j时,实际上是比较number [extra [i]]和numbers [extra [j]])。这样,在对额外数组进行排序之后,extra [0]将包含最小数字的索引,并且随着数字和颜色不变,将包含相应的颜色。
这不是很好,但是可以完成工作,我真的想不出一种更简单的方法。
附带说明,在比赛中我通常会发现C ++模板对和精美的地图是必不可少的;)
如果我们保留带有索引的第三个数组,并对其进行排序,则可以将定制的比较器与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
请注意,我们必须使用"整数"而不是" 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]]); }
更新:好的,看来其他人已经击败了我。我没有XP。
编写自己的排序方法就足够了吗?一个简单的bubblesort可能会很快编码(并正确编写)。不需要额外的类或者比较器。
一种快速的技巧是将两个阵列与移位结合在一起。制作一个long数组,使最高有效的32位是数字,而最低有效的32位是颜色。使用排序方法,然后解压缩。
在C中执行此操作的最简单方法是Bubblesort +双指针。当然,最快的将是quicksort +两个指针。当然,第二个指针保持两个数组之间的相关性。
我宁愿将存储在两个数组中的值定义为一个结构,并在单个数组中使用该结构。然后在其上使用quicksort。我们可以通过调用compare函数来编写sort的通用版本,然后可以为每个struct编写该函数,但是我们已经知道:)
示例说明使用第三索引数组。不知道这是否是最好的实现。
`
import java.util.*;
爪哇
公共类排序{
私有静态无效printTable(字符串标题,Integer []数字,
Integer []颜色,Integer [] sortOrder){
System.out.println(标题+
" \ n没有数字色" +
" \ n ----------------");
for(int i = 0; i <sortOrder.length; i ++){
System.out.printf("%x%d%d \ n",
i,numbers [sortOrder [i]],colors [sortOrder [i]]);
}
}
公共静态void main(String [] args){
最终的Integer []数字= {1,4,3,4,2,6};
最终的Integer []颜色= {0x50,0x34,0x00,0xfe,0xff,0xff};
Integer [] sortOrder = new Integer [numbers.length];
//创建索引数组。
for(int i = 0; i <sortOrder.length; i ++){
sortOrder [i] = i;
}
printTable(" \ n未排序",数字,颜色,sortOrder);
Arrays.sort(sortOrder,new Comparator <Integer>(){
public int compare(Integer a,Integer b){
返回数字[b]-数字[a];
}});
printTable(" \ n按数字排序",数字,颜色,sortOrder);
Arrays.sort(sortOrder,new Comparator <Integer>(){
public int compare(Integer a,Integer b){
返回颜色[b]-颜色[a];
}});
printTable(" \ n按颜色排序",数字,颜色,sortOrder);
}
}
`
输出应如下所示:
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
使用树图