Java中匹配数组的排序
假设我有两个数组(在Java中) int[]数字;和int[]颜色 数字的每个第i个元素对应于其颜色的第i个元素。 例如,数字={4,2,1} 颜色={0x11,0x24,0x01};表示数字4为颜色0x11,数字2为0x24,以此类推 我想对数字数组进行排序,但仍然保留该数组,以便每个元素在颜色上与其对匹配 例如,数字={1,2,4}; 颜色={0x01,0x24,0x11} 最干净、最简单的方法是什么?阵列有几千个项目,因此最好是到位,但不是必需的。使用Arrays.sort()和自定义比较器有意义吗?最好尽可能多地使用库函数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吧;您将如何用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];
}
}