【问题标题】:Sort and rearrange (distinct) arrays排序和重新排列(不同的)数组
【发布时间】:2015-08-16 01:04:12
【问题描述】:

我有两个int[] 数组IJ 如下:

int[] I = { 1, 2, 4, 5, 3 };
int[] J = { 8, 7, 6, 3, 2 };

我想对I 进行排序,然后使用相同的索引重新排列J,以便两个数组保持注册状态。结果应该是:

I = { 1, 2, 3, 4, 5 };
J = { 8, 7, 2, 6, 3 };

【问题讨论】:

  • 您想对I 进行排序,然后使用排序后的I 的相同索引结果重新排列J
  • 是的,没错。在 Matlab 中你会这样做: [sortedA idx] = sort(A); B(idx)
  • 简单答案:定义一个有两个整数的类。一个是来自I 的值,另一个可以是来自J 的相应值,也可以是索引本身(0、1、...4)。要么会工作。为简单地比较来自I 的值的类定义一个比较器。然后使用该比较器进行排序,来自J 的值或索引将与来自I 的值保持在一起。这就是您可以使用 Java 的内置 sort 来做到这一点的方法(而不是 Elliott 的回答,要求您编写自己的排序算法)。
  • 感谢所有回复,非常有帮助!

标签: java arrays sorting


【解决方案1】:

我会首先在int[] 中为swap 元素编写一个例程。比如,

public static void swap(int[] arr, int i, int j) {
    if (i == j) {
        return;
    }
    int t = arr[i];
    arr[i] = arr[j];
    arr[j] = t;
}

然后你可以使用它和Arrays.toString(int[]) 之类的东西

public static void main(String[] args) {
    int[] I = { 1, 2, 4, 5, 3 };
    int[] J = { 8, 7, 6, 3, 2 };
    for (int i = 0; i < I.length - 1; i++) {
        for (int j = i + 1; j < I.length; j++) {
            if (I[i] > I[j]) {
                swap(I, i, j);
                swap(J, i, j);
            }
        }
    }
    System.out.printf("I = %s%n", Arrays.toString(I));
    System.out.printf("J = %s%n", Arrays.toString(J));
}

输出是(按要求)

I = [1, 2, 3, 4, 5]
J = [8, 7, 2, 6, 3]

【讨论】:

  • @RishavKundu 优化留给读者作为练习。
【解决方案2】:

这也可以通过 Java 8 IntStream 和表示 2 元组的附加 Pair 类来完成(我知道,这有点难看,因为我们必须将值复制回数组):

public class Main {

    public static void main(String[] args) {

        final int[] I = {1, 2, 4, 5, 3};
        final int[] J = {8, 7, 6, 3, 2};

        List<Pair> pairs = IntStream.range(0, I.length)
                .mapToObj(n -> new Pair(I[n], J[n]))
                .sorted((p1, p2) -> p1.i - p2.i)
                .collect(Collectors.toList());

        for (int k=0; k < pairs.size(); k++) {
            Pair p = pairs.get(k);
            I[k] = p.i;
            J[k] = p.j;
        }

        System.out.println(Arrays.toString(I));
        System.out.println(Arrays.toString(J));
    }

    public static class Pair {
        public int i,j;

        public Pair(int i, int j) {
            this.i = i;
            this.j = j;
        }
    }
}

输出:

[1, 2, 3, 4, 5]
[8, 7, 2, 6, 3]

保持数组同步不是很漂亮,我强烈建议通过使用元组对象数组来正确建模。然后,它就简单多了:

public class Main {

    public static void main(String[] args) {

        final Pair[] P = {new Pair(1,8), new Pair(2,7), new Pair(4,6),
                          new Pair(5,3), new Pair(3,2)};

        Arrays.sort(P, (p1, p2) -> p1.i - p2.i);
        System.out.println(Arrays.toString(P));
    }

    public static class Pair {
        public int i,j;

        public Pair(int i, int j) {
            this.i = i;
            this.j = j;
        }

        @Override
        public String toString() {
            return String.format("(%d, %d)", i, j);
        }
    }
}

输出:

[(1, 8), (2, 7), (3, 2), (4, 6), (5, 3)]

【讨论】:

    【解决方案3】:

    正如@ajb 在上面的 cmets 中所指出的,实现这一点的最简单方法是使用对元组建模的类。

    这样做的好处是您可以使用 Arrays.sort 内置函数,这样您就无需编写自己的排序算法。另一方面,将数据从元组传输到原始数组会产生额外的开销。

    但是,您可能会发现,在您的应用程序中,您可以直接使用 Tuple 对象,而无需将它们传回数组。

    import java.util.*;
    
    class Tuple implements Comparable<Tuple>
    {
        int x;
        int y;
        Tuple(int a, int b)
        {
            x = a;
            y = b;
        }
    
        public int compareTo(Tuple another)
        {
            return Integer.compare(x, another.x);
        }
    }
    
    class Main
    {
        public static void main(String args[])
        {
            int a[] = {1, 2, 4, 5, 3};
            int b[] = {8, 7, 6, 3, 2};
            Tuple arr[] = new Tuple[a.length];
            for (int i=0;i<a.length;i++)
                arr[i] = new Tuple(a[i], b[i]);
            Arrays.sort(arr);
            for (int i=0;i<a.length;i++)
            {
                a[i] = arr[i].x;
                b[i] = arr[i].y;
            }
    
            System.out.println(Arrays.toString(a));
            System.out.println(Arrays.toString(b));
        }
    }
    

    还有输出:

    [1, 2, 3, 4, 5]
    [8, 7, 2, 6, 3]
    

    【讨论】:

      猜你喜欢
      • 2012-08-11
      • 1970-01-01
      • 1970-01-01
      • 2012-02-14
      • 2016-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多