如何对两个数组进行排序,其中一个数组根据另一个数组的排序进行排序?

问题描述 投票:0回答:4

所以我已经多次遇到这个问题了。让我解释一下。假设我有这两个数组:

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排序的。我需要一种方法以尽可能最快的方式进行这种排序。

对此有什么建议吗?

java arrays algorithm sorting mapping
4个回答
3
投票

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
投票

您可以创建一个二维数组,其中每个元素都是长度为

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]);
}

1
投票

您可以尝试根据您实际拥有的数据创建一个对象。在这种情况下,对象可能包含两个字段:数字和出现次数。然后实现一个比较器来通过出现字段进行比较。


0
投票

如果您可以提倡该方法不是上面提到的并行收集反模式(您可以轻松地用于大数据),那么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);
© www.soinside.com 2019 - 2024. All rights reserved.