3 回答

TA貢獻(xiàn)1878條經(jīng)驗(yàn) 獲得超4個(gè)贊
由于您不能使用現(xiàn)有的 Comparator 或排序算法,因此您需要自己完成。我已經(jīng)實(shí)現(xiàn)了一個(gè)static函數(shù)lessOrEqual,它接受 2 個(gè)Student實(shí)例,比較它們并返回是否s1小于或等于s2。 larger(Student s1, Student s2)僅當(dāng)s1大于時(shí)返回真s2。可以有很多不同的方法來做到這一點(diǎn),這真的取決于你,因?yàn)樗皇且粋€(gè)比較。該函數(shù)首先檢查成績,如果成績匹配,它將檢查姓名并相應(yīng)地返回。
編輯:如您所見,我替換lessOrEqual為larger因?yàn)槲艺谑褂玫倪x擇排序需要找到larger。這是相同的效果,我這樣做只是為了更好的可讀性。
然后我實(shí)現(xiàn)了另一個(gè)static接受ArrayList<Student>、排序并返回排序的函數(shù)。使用的排序算法非?;荆哼x擇排序。它的 O(N^2) 效率不高,但為了簡單起見,我在下面的演示中這樣做了。
代碼:
import java.util.ArrayList;
public class Student {
private String name;
private Integer rollNumber;
private int m1;
private int m2;
private int m3;
private int totMarks;
public static boolean larger(Student s1, Student s2){
if(s1.totMarks < s2.totMarks) return false;
else if (s1.totMarks > s2.totMarks) return true;
// compare names
else return s1.name.compareTo(s2.name) > 0;
}
public static ArrayList<Student> sortSelection(ArrayList<Student> list){
for(int i=0; i<list.size(); i++){
for(int j=i+1; j< list.size(); j++){
if(larger(list.get(i), list.get(j))){ // swap
Student temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
}
}
return list;
}
//Getter setter
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getTotMarks(){
return totMarks;
}
public void setTotMarks(int totMarks){
this.totMarks = totMarks;
}
@Override
public String toString(){
return String.format("Name: %20s - Total Marks: %3d", name, totMarks);
}
public static void main(String[] args){
Student s1 = new Student();
Student s2 = new Student();
Student s3 = new Student();
Student s4 = new Student();
s1.setName("John Smith");
s1.setTotMarks(98);
s2.setName("Jack Smith");
s2.setTotMarks(98);
s3.setName("Adam Noob");
s3.setTotMarks(100);
s4.setName("Ved Parkash");
s4.setTotMarks(99);
ArrayList<Student> list = new ArrayList<>();
list.add(s4);
list.add(s3);
list.add(s1);
list.add(s2);
System.out.println("Array before sorting:");
for(int i=0; i<list.size(); i++){
System.out.println(list.get(i).toString());
}
Student.sortSelection(list);
System.out.println("Array after sorting:");
for(int i=0; i<list.size(); i++){
System.out.println(list.get(i).toString());
}
}
}
輸出:
Array before sorting:
Name: Ved Parkash - Total Marks: 99
Name: Adam Noob - Total Marks: 100
Name: John Smith - Total Marks: 98
Name: Jack Smith - Total Marks: 98
Array after sorting:
Name: Jack Smith - Total Marks: 98
Name: John Smith - Total Marks: 98
Name: Ved Parkash - Total Marks: 99
Name: Adam Noob - Total Marks: 100
筆記:
1) 查看學(xué)生添加到列表中的順序,它是 4,3, 1 然后是 2。這是為了證明它在成績匹配時(shí)根據(jù)姓名排序(Jack Smith vs John Smith)。
2) 我對(duì)學(xué)生進(jìn)行硬編碼以制作更好的演示。
3) 正如您可能注意到的那樣,我沒有設(shè)置任何其他變量,因?yàn)閱栴}完全是關(guān)于排序的,唯一對(duì)排序有貢獻(xiàn)的變量是:name和totMarks。你將不得不做剩下的事情。
4) 我正在使用ArrayList,但不限于此,通過簡單的更改,您可以在普通Student[]數(shù)組上使用它。
5)函數(shù)larger不一定是static,你可以把它做成一個(gè)成員函數(shù),用不同的方式使用。例如,上面的代碼將更改為:
public boolean larger(Student other){
if(totMarks < other.totMarks) return false;
else if (totMarks > other.totMarks) return true;
// compare names
else return name.compareTo(other.name) > 0;
}
public static ArrayList<Student> sortSelection(ArrayList<Student> list){
for(int i=0; i<list.size(); i++){
for(int j=i+1; j< list.size(); j++){
// comparison way changes accordingly
if(list.get(i).larger(list.get(j))){ // swap
Student temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
}
}
return list;
}

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超8個(gè)贊
為了保持簡單(即 KISS 原則)并解釋我與復(fù)合鍵相關(guān)的“提示”,以下是工作示例。
解決方案的“關(guān)鍵”是讓樹自然地對(duì)數(shù)據(jù)進(jìn)行排序(不是,恕我直言,通過提供手動(dòng)排序來添加代碼使其變得更加復(fù)雜)。因此,學(xué)生類需要返回一個(gè)樹可以自然排序的鍵。
為了產(chǎn)生所需的排序結(jié)果,樹的鍵是(總分,學(xué)生姓名)。
這是修改后的 Student 類(減去 getter 和 setter,但我確實(shí)添加了一個(gè)新的構(gòu)造函數(shù)以使我的生活更輕松):
public class Student {
private String name;
private Integer rollNumber;
private int m1;
private int m2;
private int m3;
private int totMarks;
//Getter setter
public Student() {
}
public Student(String name, Integer rollNumber, int m1, int m2, int m3) {
this.name = name;
this.rollNumber = rollNumber;
this.m1 = m1;
this.m2 = m2;
this.m3 = m3;
this.totMarks = m1 + m2 + m3;
}
public String getKey() {
// return String.format("%d-%s", totMarks, name); // WRONG!
return String.format("%04d-%s", totMarks, name); // Right
}
public String toString() {
return String.format("%06d: %s - %d", rollNumber, name, totMarks);
}
}
請(qǐng)注意,方法中有一行注釋掉的代碼getKey帶有注釋W(xué)RONG。這與我用個(gè)位數(shù)分?jǐn)?shù)測試的暗示有關(guān)。嘗試交換兩行代碼以查看正確和錯(cuò)誤的結(jié)果。
這是主要的,我刪除了所有掃描儀的東西——再次讓我的生活更輕松。希望您可以關(guān)注它并重新添加到您的掃描儀循環(huán)中。
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class StudentData {
public static void main(String[] args) {
// Initialise a list of students (as I don't want to rekey all the details each
// time I run the program).
List<Student> studentList = Arrays.asList(
new Student("Fred", 1, 2, 2, 2), /* Score of 6 */
new Student("John", 2, 2, 3, 3), /* Score of 8 */
new Student("Jane", 3, 20, 25, 30), /* Score of 75 */
new Student("Julie", 4, 20, 15, 10) /* Score of 45 */
// add as many new students as you like, and reorder them
// as much as you like to see if there is any difference in the
// result (there shouldn't be).
);
// Note the key of the tree is of type String - not Integer.
// This is the heart of the algorithm, the tree will be "sorted"
// on the natural key provided. This "natural key" is in fact
// a compound key that is generated by combining the total score
// and the student name.
Map<String,Student> map = new TreeMap<String,Student>();
for (Student ss : studentList) {
map.put(ss.getKey(),ss);
}
//stdList.forEach(System.out::print);
for(Map.Entry<String,Student> m :map.entrySet()) {
System.out.println(m);
}
}
}
我希望您同意這是一個(gè)更簡單的解決方案。還有一個(gè)潛在的性能優(yōu)勢,因?yàn)閷W(xué)生在被加載到樹中時(shí)被排序(即一次)。我認(rèn)為這種排序的性能是 log(n)。檢索排序可能是 n log(n) 或更糟。

TA貢獻(xiàn)1875條經(jīng)驗(yàn) 獲得超3個(gè)贊
不是將值存儲(chǔ)為 student,而是將它們存儲(chǔ)為 (name, student) 的映射,這樣當(dāng)遇到具有相同標(biāo)記的學(xué)生時(shí),就會(huì)將其添加到映射中。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enetr the number of Student");
int totalStudent = sc.nextInt();
Map<Integer, Map<String, Student>> map = new TreeMap<>();
for(int i =0;i<totalStudent;i++) {
Student ss = new Student();
System.out.println("Enter the Student roll number");
ss.setRollNumber(sc.nextInt());
System.out.println("Enter the Student Name");
ss.setName(sc.next());
System.out.println("Enter the m1 marks ");
ss.setM1(sc.nextInt());
System.out.println("Enetr the m2 marks ");
ss.setM2(sc.nextInt());
System.out.println("Enter the m3 marks ");
ss.setM3(sc.nextInt());
ss.setTotMarks(ss.getM1()+ss.getM2()+ss.getM3());
Integer key = ss.getTotMarks();
if (map.get(key) == null){ // if this is a new key in the map, then create a new TreeMap and put it
final TreeMap<String, Student> nameAndStudentMap = new TreeMap<>();
nameAndStudentMap.put(ss.getName(), ss);
map.put(key, nameAndStudentMap);
}else { // if the key already existed, then get the map stored and add to it.
map.get(key).put(ss.getName(), ss);
}
}
//stdList.forEach(System.out::print);
for(Map.Entry<Integer,Map<String, Student>> m :map.entrySet()) {
for (Map.Entry<String, Student> nameAndStudent : m.getValue().entrySet()) {
System.out.println(m.getKey() + " = " + nameAndStudent.getValue());
}
}
}
添加回答
舉報(bào)