【发布时间】:2020-05-04 22:28:58
【问题描述】:
在我的程序中,我接受了一个成绩列表和一个姓名列表。等级的顺序与名称的顺序相对应。我想将成绩从最低到最高或从最高到最低排序(没关系),但要保持它,以便人 a 和人 a 的成绩的索引相同。
【问题讨论】:
-
不要。将成绩和姓名组合到您自己类型的列表中,例如学生。
在我的程序中,我接受了一个成绩列表和一个姓名列表。等级的顺序与名称的顺序相对应。我想将成绩从最低到最高或从最高到最低排序(没关系),但要保持它,以便人 a 和人 a 的成绩的索引相同。
【问题讨论】:
首先,由于您使用的是 Java,自然的方法是创建一个类,例如学生,具有年级和姓名实例成员。然后,您将拥有一个可以排序的学生列表,这自然会将关联的数据保存在一起。
但是,如果您需要坚持使用单独的列表,诀窍是将索引列表排序到成绩列表中,而不是成绩列表本身。在比较器中,您比较的是成绩列表中相应位置的成绩,而不是索引。
List<String> grades = Arrays.asList("F", "A", "C", "D");
List<String> names = Arrays.asList("Tom", "Sue", "Dick", "Harry");
List<Integer> indexes = new ArrayList<>();
for(int i=0; i<grades.size(); i++) indexes.add(i);
indexes.sort((i1, i2) -> grades.get(i1).compareTo(grades.get(i2)));
for(Integer i : indexes)
System.out.format("%s : %s%n", names.get(i), grades.get(i));
List<String> sortedGrades = new ArrayList<>();
List<String> sortedNames = new ArrayList<>();
for(Integer i : indexes)
{
sortedGrades.add(grades.get(i));
sortedNames.add(names.get(i));
}
System.out.println();
System.out.println(sortedNames);
System.out.println(sortedGrades);
输出:
Sue : A
Dick : C
Harry : D
Tom : F
[Sue, Dick, Harry, Tom]
[A, C, D, F]
只是为了比较,下面是使用 Student 类的方法:
class Student
{
String grade;
String name;
public Student(String name, String grade)
{
this.name = name;
this.grade = grade;
}
}
测试:
List<String> grades = Arrays.asList("F", "A", "C", "D");
List<String> names = Arrays.asList("Tom", "Sue", "Dick", "Harry");
List<Student> students = new ArrayList<>();
for(int i=0; i<grades.size(); i++)
students.add(new Student(names.get(i), grades.get(i)));
students.sort((s1, s2) -> s1.grade.compareTo(s2.grade));
for(Student s : students)
System.out.format("%s : %s%n", s.name, s.grade);
输出:
Sue : A
Dick : C
Harry : D
Tom : F
【讨论】:
最好创建一个对象来表示您的学生(其中将包含姓名和成绩作为属性),而不是尝试同步不同数组的顺序。
考虑到您的两个数组的顺序已经相同(grades[0] 匹配 names[0] 等等),您基本上需要:
Student.java
package com.stackoverflow;
import java.math.BigDecimal;
public class Student {
private String name;
private BigDecimal grade;
public Student(String name, BigDecimal grade) {
this.name = name;
this.grade = grade;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getGrade() {
return grade;
}
public void setGrade(BigDecimal grade) {
this.grade = grade;
}
}
GradeComparator.java
package com.stackoverflow;
import java.util.Comparator;
public class GradeComparator implements Comparator<Student> {
@Override
public int compare(Student source, Student target) {
return source.getGrade().compareTo(target.getGrade());
}
}
Example.java
package com.stackoverflow;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class Example {
public static void main(String[] args) {
String[] names = {"John", "Mary", "Paul", "Alex"};
BigDecimal[] grades = {BigDecimal.valueOf(5), BigDecimal.valueOf(3), BigDecimal.valueOf(8), BigDecimal.valueOf(2)};
List<Student> studentList = new ArrayList<>();
for (int i = 0; i < names.length; i++) {
studentList.add(new Student(names[i], grades[i])); // make sure arrays have the same size so you don't get an ArrayOutOfBoundsException
}
studentList.sort(new GradeComparator()); // list is now sorted in ascending order
studentList.sort(new GradeComparator().reversed()); // list is now sorted in descending order
}
}
【讨论】:
这个任务你可以使用键索引计数排序,算法的运行时间是linear,我假设你在浮点数后面最多有2个小数所以我使用Number * 100
public static void main(String[] args) {
String[] names = { "Jack", "Sara", "Smith", "Nour", "Salah" };
double[] degrees = new double[] { 90.0, 98.6, 98.5, 85.6, 100.0 };
int N = degrees.length;
int R = 101 * 100;
int[] count = new int[R + 1];
double[] aux = new double[N];
String[] aux2 = new String[N];
for (int i = 0; i < N; i++) {
int pos = (int) (degrees[i] * 100) + 1;
count[pos]++;
}
for (int r = 0; r < R; r++)
count[r + 1] += count[r];
for (int i = 0; i < N; i++) {
int pos = (int) (degrees[i] * 100);
aux[count[pos]] = degrees[i];
aux2[count[pos]++] = names[i];
}
for (int i = 0; i < N; i++) {
degrees[i] = aux[i];
names[i] = aux2[i];
}
for (int i = 0; i < N; i++) {
System.out.print(names[i] + ": ");
System.out.println(degrees[i]);
}
}
,输出
Nour: 85.6
Jack: 90.0
Smith: 98.5
Sara: 98.6
Salah: 100.0
【讨论】: