所以我已经多次遇到这个问题了。让我解释一下。假设我有这两个数组:
A1={1,2,3,4,5,6,7,8,9,10};
和
A2={1,2,3,0,2,1,1,0,0,0};
。我的要求是这样的:
当我对 A2 进行排序时,无论 A2 中发生什么元素交换和移动,A1 中也应该发生同样的情况。基本上我试图使用两个数组创建一个 Map,而不是创建一个实际的 HashMap 或 HashTable。
最后数组应如下所示:
A1={4,8,9,10,1,6,7,2,5,3};
和A2={0,0,0,0,1,1,1,2,2,3};
。两个数组对应的值仍然相同,但数据是根据A2排序的。我需要一种方法以尽可能最快的方式进行这种排序。
对此有什么建议吗?
Pair Class 可以做到这一点。
import java.util.*;
public class Main
{
static class Pair implements Comparable<Pair>
{
int a1;
int a2;
Pair (int a1, int a2) //constructor
{
this.a1 = a1;
this.a2 = a2;
}
public int compareTo(Pair other) //making it only compare a2 values
{
return this.a2 - other.a2;
}
}
public static void main(String[] args)
{
int[] A1 = {1,2,3,4,5,6,7,8,9,10};
int[] A2 = {1,2,3,0,2,1,1,0,0,0};
Pair[] pairs = new Pair[A1.length];
for (int i = 0; i < pairs.length; i++)
{
pairs[i] = new Pair(A1[i], A2[i]);
}
Arrays.sort(pairs);
//printing values
for (int i = 0; i < A1.length; i++)
{
System.out.print(pairs[i].a1 + " ");
}
System.out.println();
for (int i = 0; i < A2.length; i++)
{
System.out.print(pairs[i].a2 + " ");
}
}
}
通过创建一个包含 2 个变量
a1
和 a2
的 Pair 类,您可以重写 compareTo
方法以仅比较 a2
值,这样当调用 Arrays.sort
时,Pair 数组中的对将仅根据 a2
值进行交换。然后,您可以访问成对的值并将其打印出来。这将产生您想要的输出。
您可以创建一个二维数组,其中每个元素都是长度为
2
的数组,并根据第二个元素对其进行排序。
int[] A1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, A2 = { 1, 2, 3, 0, 2, 1, 1, 0, 0, 0 };
final int[][] res = new int[A1.length][2];
for(int i = 0; i < res.length; i++) {
res[i] = new int[] {A1[i], A2[i]};
}
Arrays.sort(res, (a,b)->Integer.compare(a[1], b[1]));
//Alternatively, Arrays.sort(res, Comparator.comparingInt(a -> a[1]));
for(final int[] a : res) {
System.out.println(a[0] + " " + a[1]);
}
您可以尝试根据您实际拥有的数据创建一个对象。在这种情况下,对象可能包含两个字段:数字和出现次数。然后实现一个比较器来通过出现字段进行比较。
如果您可以提倡该方法不是上面提到的并行收集反模式(您可以轻松地用于大数据),那么fastutils在类
it.unimi.dsi.fastutil.Arrays
中提供了一个解决方案。有多种带有显式比较器和交换器的排序方法。假设您想要对 UUID 进行排序(每个 UUID 存储为两个长整型),但保留其原始索引的跟踪。给你:
long[] uuids = ..
int[] indexes = new int[uuids.length / 2];
// fill indexes
java.util.Arrays.parallelSetAll(indexes, i -> i);
IntComparator comparator = (k1, k2) -> {
int cmp = Long.compare(uuids[2 * indexes[k1]], uuids[2 * indexes[k2]]);
if (cmp == 0) {
cmp = Long.compare(uuids[2 * indexes[k1] + 1], uuids[2 * indexes[k2] + 1]);
}
return cmp;
};
Swapper swapper = (k1, k2) -> {
int tmp = indexes[k1];
indexes[k1] = indexes[k2];
indexes[k2] = tmp;
};
it.unimi.dsi.fastutil.Arrays.parallelQuickSort(0, indexes.length, comparator, swapper);