刚学二维数组
已经将总成绩求出来了,不知道要怎么从求出的总成绩sum拉出来进行大小排序
public class SortArray {
public static void main(String[] args) {
int[][] scores = { { 80, 90, 70 }, { 60, 70, 80 }, { 90, 80, 70 } };
int[] sum = new int[scores.length];
// 计算每个学生的总成绩并存储到一维数组中
for (int i = 0; i < scores.length; i++) {
int total = 0;
for (int j = 0; j < scores[i].length; j++) {
total += scores[i][j];
}
sum[i] = total;
}
// 对一维数组进行排序
Arrays.sort(sum);
// 遍历二维数组,输出每个学生的信息和排名
for (int i = 0; i < scores.length; i++) {
int rank = scores.length - Arrays.binarySearch(sum, sum[i]);
System.out.println("第" + rank + "名:" + "总成绩为" + sum[i] + ",详细成绩为" + Arrays.toString(scores[i]));
}
}
}
定义一个全局变量不就可以啦,不用拉出来
假设你已经定义了一个二维数组 scores,其中每一行表示一个学生的成绩,每一列表示一个科目的成绩,那么你可以通过以下代码计算每个学生的总成绩:
```java
int[] totalScores = new int[scores.length];
for (int i = 0; i < scores.length; i++) {
int total = 0;
for (int j = 0; j < scores[i].length; j++) {
total += scores[i][j];
}
totalScores[i] = total;
}
这段代码会遍历每一行,将每行的所有列相加得到总成绩,并存储在一个一维数组 totalScores 中。接下来你可以对 totalScores 进行排序:
```
Arrays.sort(totalScores);
这会将 totalScores 数组按照从小到大的顺序排序。如果你想按照从大到小的顺序排序,可以使用 Arrays.sort(totalScores, Collections.reverseOrder())。注意,这个方法只能用于包装类型的数组,如果你的数组是基本类型,你需要将它们转换为包装类型再排序。
输入:
7
1
2
4
8
16
32
64
输出:
3
3
6
7
1. 首先,我们可以用动态规划来标记可以添加到组合中的数据。
定义数组 scores = {-1, 1, 2, 4, 8, 16, 32, 64},scores[i] 表示编号为 i 的题目的分数(i 在 1 ~ n之间) 。
我们定义 r[i][j] 为总分为 i 时,求标号为 j j+1 … n 的题目能否组合出总分 i。
比如 r[100][7] 表示总分为 100 时,第 7 题能否拼出总分,因为第 7 题的分数为 scores[7] = 64,所以拼不出来,r[100][7] = false,显然 r[64][7] = true。再比如 r[100][6] 表示总分为 100 时,第 6/7 题能否拼出总分,因为第 6 题的分数为 scores[6] = 32,所以拼不出来,但是 r[32][6] = true(第6题分数为32),r[64][6] = true(第 7 题分数为 64),r[96][6] = true(第 6 和 7 题的总分为 96)。
因此我们可以列表:
scores[i] | i\j | 0 | … | 32 | … | 64 | … | 96 | … | 100 |
---|---|---|---|---|---|---|---|---|---|---|
64 | 7 | true | … | … | ||||||
32 | 6 | true | true | … | true | … | ||||
16 | 5 | … | … | |||||||
8 | 4 | … | … | |||||||
4 | 3 | … | … | |||||||
2 | 2 | … | … | |||||||
1 | 1 | … | … |
递推公式为:
当r[i+1][j] == true(组合中无第 i 题) 或者 r[i+1][j-score[i]] == true (组合中有第 i 题)时
r[i][j] = true
为方便处理第 i 题一定可以组合总分为 score[i] 的情况(只用第 i 题来组合),我们令 r[i+1][0] == true
(仅为计算方便,没有实际意义)。
另一个边界条件是表中第一行的数据,r[n][score[n]] = true
。
问题不断推导我们就能得出 r[1][100] 的值,也就是原问题是否有解。
伪代码为
int SUM = 100;
void markResults(int n, int[] scores, boolean[][] r)
{
// 第一行的数据
j: 1 -> SUM
r[n][j] = false;
r[n][0] = true;
r[n][scores[n]] = true;
i: n-1 -> 1
j: 0 -> SUM
如果 r[i + 1][j] == true
|-- r[i][j] = true;
|-- 如果 j + scores[i] <= SUM
|-- r[i][j + scores[i]] = true;
}
2. 确定有解之后,我们可以尝试输出组合。
r[1][100] 有解,而第 1 题的分数为 1,那么有两种情况,如果 r[2][100] 有解,那么组合中可以没有第 1 题,如果 r[2][99] 有解,那么组合中可以有第 1 题。总之,这两种情况至少有一种满足,才会使 r[1][100] 有解。
伪代码:
void printResults(Stack<Integer> stack, int index, int sum)
{
...
// 当前问题有解
如果 r[index][sum] == true
// 组合中没有第 index 题
|-- 如果 r[index + 1][sum] == true
|-- printResults(stack, index + 1, sum);
// 组合中有第 index 题
|-- 如果 sum - scores[index] >= 0 且 r[index + 1][sum - scores[index]] == true
|-- stack.push(index);
|-- printResults(stack, index + 1, division);
|-- stack.pop();
}
以上是打印组合是的递推公式,我们还要考虑边界情况:
void printResults(Stack<Integer> stack, int index, int sum)
{
如果 sum <= 0
|-- 打印 stack
// 迭代到了表格的第一行,要么是这一行有解,要么是 n == 1
如果 index == n
// 这一行有解
如果 score[n] == sum
|-- stack.push(n);
|-- 打印 stack
|-- stack.pop();
|-- return;
// n == 1,小明只找到了一个题目,且这个题目的分数不等于 SUM
否则
|-- return;
...
}
综上,Java 代码如下:
public static void findSumN() {
// Scanner in = new Scanner(System.in);
// int n = in.nextInt();
// int[] scores = new int[n];
// for (int i = 0; i < n; i++) {
// scores[i] = in.nextInt();
// }
int n = 7;
int[] scores = {0, 1, 2, 4, 8, 16, 32, 64};
boolean[][] r = new boolean[n + 1][SUM + 1];
markResults(n, scores, r);
printResults(n, scores, r);
}
/*
3
3
6
7
*/
private static void printResults(int n, int[] scores, boolean[][] r) {
Deque<Integer> stack = new ArrayDeque<>(n);
printResults(n, scores, r, stack, 1, SUM);
}
private static void printResults(int n, int[] scores, boolean[][] r,
Deque<Integer> stack, int index, int sum) {
if (sum == 0) {
printStack(stack);
}
if (index == n) {
if (r[index][sum]) {
stack.push(index);
printStack(stack);
stack.pop();
}
return;
}
if (r[index][sum]) {
if (r[index + 1][sum]) {
printResults(n, scores, r, stack, index + 1, sum);
}
int division = sum - scores[index];
if (division >= 0 && r[index + 1][division]) {
stack.push(index);
printResults(n, scores, r, stack, index + 1, division);
stack.pop();
}
}
}
private static void printStack(Deque<Integer> stack) {
if (stack.size() == 0) {
return;
}
System.out.println(stack.size());
Iterator<Integer> iterator = stack.descendingIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
private static void markResults(int n, int[] scores, boolean[][] r) {
for (int j = 1; j <= SUM; j++) {
r[n][j] = false;
}
r[n][0] = true;
r[n][scores[n]] = true;
for (int i = n - 1; i > 0; i--) {
for (int j = 0; j <= SUM; j++) {
if (r[i + 1][j]) {
r[i][j] = true;
if (j <= SUM - scores[i]) {
r[i][j + scores[i]] = true;
}
}
}
}
}
我无法为您解决该问题。