【问题标题】:Sorting 2 dimensional arrays in Java - skipping the first index在 Java 中对二维数组进行排序 - 跳过第一个索引
【发布时间】:2013-08-18 12:25:04
【问题描述】:

我在 Java 中有一个二维数组,如下所示:

每个元素/作业都有一个:

  • index[0]中的作业号;
  • index[1]中的作业到达时间;和
  • index[2] 中的工作突增时间
jobs[0][0] = 1
jobs[0][1] = 0
jobs[0][2] = 5

jobs[1][0] = 2
jobs[1][1] = 2
jobs[1][2] = 19

jobs[2][0] = 3
jobs[2][1] = 4
jobs[2][2] = 10

首先,我想根据到达时间对它们进行排序,这是根据 index[1] 幸运的,我使用以下代码做到了:

Arrays.sort(jobs, new Comparator<int[]>(){
    public int compare(int[] a, int[] b) {
        return a[1] - b[1];
    }
});


现在,我的问题是我想根据索引 [2] 的突发时间对其进行排序。这是 TWIST ......我怎样才能根据突发时间(索引 [2])跳过第一个元素对其进行排序? 我希望 job[0] 保留在数组顶部并按索引 [2] 对剩余元素进行排序 - 突发时间。像这样:
jobs[0][0] = 1
jobs[0][1] = 0
jobs[0][2] = 5

jobs[1][0] = 3
jobs[1][1] = 4
jobs[1][2] = 10

jobs[2][0] = 2
jobs[2][1] = 2
jobs[2][2] = 19

作业按突发时间排序,作业 1 保持在最前面。 通过我上面提供的代码来实现它会好得多。谢谢

【问题讨论】:

  • BOLD 太多会伤眼睛。

标签: java arrays sorting data-structures multidimensional-array


【解决方案1】:

首先,您应该使用集合而不是数组。其次,当你可以使用对象时,你不应该使用数组:

public class Job {
    private int number;
    private int arrival;
    private int burst;

    // constructor and getters omitted for brevity.
}

然后您可以使用List&lt;Job&gt;,而不是int[][]。只看结构的类型,就已经比较清晰易读了。具有命名属性、可能具有不同类型的属性以及能够使用方法添加行为,是 OO 的全部内容的一部分。比int[] 更具可读性、安全性和可维护性。

好消息是 List 比数组具有更多的功能。例如,您可以获取一个子列表,然后对该子列表进行排序:

List<Job> jobsExceptFirstOne = allJobs.subList(1);
Collections.sort(jobsExceptFirstOne, new Comparator<Job>() {
    @Override
    public int compare(Job left, Job right) {
        return Integer.compare(left.getBurst(), right.getBurst());
    }
});

瞧。问题解决了。

【讨论】:

  • 感谢您的回答,先生,但不幸的是,我不知道如何使用 LISTS,它现在的代码很长,如果我将所有内容都转为 LISTS,它的变化会很大:(
  • 然后学习如何使用它们。这是任何 Java 开发人员都必须知道的。坚持你现在的糟糕设计会让事情变得越来越糟。你最好尽快解决这个问题。
  • 希望我会先生,非常感谢先生。我希望有一天我会成为像你们一样的人。专业的开发人员。非常感谢楼主
【解决方案2】:

一个简单的方法是:

int firstBurst = jobs[0][2];
jobs[0][2] = Integer.MIN_VALUE;
Arrays.sort(jobs, new Comparator<int[]>(){
    public int compare(int[] a, int[] b) {
        // don't use subtraction, this can lead to underflows
        return a[2] < b[2] ? -1 : (a[2] == b[2] ? 0 : 1);
    }
});
jobs[0][2] = firstBurst;

只需将第一项的突发设置为Integer.MIN_VALUE(相当于负无穷大的整数)。这样,它保证了第一项是最小的,所以在排序后它仍然是第一个元素。排序后,将第一项的burst重置为原始值。

编辑

通过检查documentation来验证Arrays.sort是否稳定,无意中找到了解决这个问题的最简单的版本:使用

Arrays.sort(T[] a,
            int fromIndex,
            int toIndex,
            Comparator<? super T> c)

那么你可以直接这样做:

Arrays.sort(jobs, 1, jobs.length, new Comparator<int[]>(){
    public int compare(int[] a, int[] b) {
        // don't use subtraction, this can lead to underflows
        return a[2] < b[2] ? -1 : (a[2] == b[2] ? 0 : 1);
    }
});

【讨论】:

  • 返回不应该是这样的return a[2] &lt; b[2] ? -1 : (a[2] == b[2] ? 0 : 1); 吗?
  • 先生,您的代码有效!谢谢。你能简单解释一下你的代码吗?
  • @bowmore 对吧?还是我对Collections.sort 感到困惑?
  • 这是一种稳定的排序,只是指出您在这种方法中有一些逻辑耦合。
【解决方案3】:

正如其他人所说,你应该使用更智能的集合而不是数组,如果你真的想要使用当前代码,你可以使用类似的东西:

final int[][] jobs = new int[][]{{1,0,5},{2,2,19},{3,4,10}};

 Arrays.sort(jobs, new Comparator<int[]>(){
    public int compare(int[] a, int[] b) {
        if(Arrays.equals(a, jobs[0]))
         return -1;
        else
         return a[2] - b[2];
    }
});

System.out.println(jobs[0][2]);
System.out.println(jobs[1][2]);
System.out.println(jobs[2][2]);

唯一的缺点是您的数组必须是final

【讨论】:

  • 整理出来的包括工作[0]
  • job[0] 将始终处于领先地位,这不是本意吗?
【解决方案4】:

也许会有一种使用方法:

final Integer job1 = Integer.valueOf(jobs[0][0]);
final Integer job2 = Integer.valueOf(jobs[0][1]);

return job1.compareTo(job2);

我真的不知道 valueOf(jobs[0][0]) 是否会比 valueOf(jobs[0][1]) 大,我真的不知道它们之间的关系如何,但必须有它们之间的区别,并且您应该能够根据返回的数字是大于还是小于jobs[0][0]、jobs[1][0]等之一对它们进行排序

【讨论】:

    【解决方案5】:

    使用比较器来记住第一个作业的作业编号,并在检查突发时间之前将其视为最小的。

    public class MyComparator implements Comparator<int[]> {
    
        private final int firstJob;
    
        public MyComparator(int firstJob) {
            this.firstJob = firstJob;
        }
    
        public int compare(int[] a, int[] b) {
            if (a[0] == b[0]) {
                return 0;
            }
            if (a[0] == firstJob) {
                return -1;
            }
            if (b[0] == firstJob) {
                return 1;
            }
            return Integer.compare(a[2], b[2]);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-19
      • 1970-01-01
      • 2023-01-31
      • 2018-05-17
      • 2012-04-03
      • 2014-11-29
      • 2011-10-25
      相关资源
      最近更新 更多