用Java排序2维数组 - 跳过第一个索引

时间:2013-08-16 06:56:54

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

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

每个元素/作业都有:

  • 索引[0] ;
  • 中的作业编号
  • 指数[1] 中的作业到达时间;和
  • 索引[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

首先,我想根据索引[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

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

5 个答案:

答案 0 :(得分:5)

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

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

    // constructor and getters omitted for brevity.
}

然后,您可以拥有List<Job>,而不是int[][]。仅仅通过查看结构的类型,它已经更清晰,更具可读性。命名属性(可能具有不同类型,并且能够使用方法添加行为)是OO的一部分。比int[]更具可读性,安全性和可维护性。

好消息是List具有比数组更多的功能。因此,您可以采用subList,并对该subList进行排序:

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

瞧。问题解决了。

答案 1 :(得分: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(相当于负无穷大的整数)。这样,它保证第一项是最小的,所以在排序后它仍然是第一个元素。排序后,将第一项的突发重置为原始值。

修改

通过检查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);
    }
});

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

也许有办法使用它:

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]),而我真的不知道他们是如何站在一个又一个,但必须有他们之间的差异,你应该能够根据返回的数字是大于还是小于作业[0] [0],作业[1] [0]等

答案 4 :(得分:0)

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

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