2

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

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

  • 在index[0]中的作业号;
  • index[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

首先,我想根据到达时间对它们进行排序,这是根据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 位于顶部。通过我上面提供的代码来实现它会好得多。谢谢

4

5 回答 5

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

瞧。问题解决了。

于 2013-08-16T07:12:01.903 回答
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(等于负无穷大的整数)。这样,它保证了第一项是最小的,所以在排序之后它仍然是第一个元素。排序后,将第一项的突发重置为其原始值。

编辑

通过检查文档来验证它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);
    }
});
于 2013-08-16T07:09:53.647 回答
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.

于 2013-08-16T07:22:27.187 回答
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]) 大,而且我真的不知道它们之间的关系如何,但两者之间肯定有区别它们,并且您应该能够根据返回的数字是大于还是小于 Jobs[0][0]、jobs[1][0] 等之一对它们进行排序。

于 2013-08-16T07:14:25.330 回答
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]);
    }
}
于 2013-08-16T07:17:10.310 回答