外部ソート/内部ソートの問題

6570 ワード

/*
1.問題)学号(int)、氏名(String)、国語点数、英語点数、数学点数、総点などをメンバーとするStudentクラスを作成する.
1-1.このクラスの作成者は,学号,氏名,国語点数,英語点数,数学点数のみをパラメータとして初期化処理を行う.
2.このstudentオブジェクトは、リストに格納されて管理されます.
3.Listに格納されているデータは、「学号昇順(初期状態)」の内部ソート基準を採用しています.
4.次に、合計スコアの逆順序でソートします.合計スコアが同じ場合は、名前の昇順でソートして、外部ソート基準クラスを作成できます.
合計スコア(降順)合計スコアが同じ場合は、名前による昇順-外部ソートクラス
上記のソート基準と一致するプログラムを作成してください.
5.(ただし、等号はリストに完全なデータを追加して保存してください.)
*/
package kr.or.ddit.basic;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;


//1. 학번(int), 이름(String), 국어점수, 영어점수, 수학점수, 총점, 등수를 멤버로 갖는 Student 클래스를 만든다.
class Student implements Comparable<Student>{//인터페이스라서 implement사용
	private int id;//학번
	private String name;
	private int korScore;
	private int engScore;
	private int mathScore;
	private int total;
	private int rank;
	//다른 클래스에서 못쓰게 하려고 private으로 사용
	
	//1-1 이 클래스의 생성자에서는 학번, 이름, 국어점수, 영어점수, 수학점수만 매개변수로 받아서 초기화 처리를 한다.
	public Student(int id, String name, int korScore, int engScore, int mathScore) {
		super();
		this.id = id;
		this.name = name;
		this.korScore = korScore;
		this.engScore = engScore;
		this.mathScore = mathScore;
		total = korScore+engScore+mathScore;//받아서 사용하는 게 아니라 this없어두댐
	}
	
	//private 이라 값을 뽑을려고(get) 명명한것(set)
	public int getId() {//alt+shift+s
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getKorScore() {
		return korScore;
	}

	public void setKorScore(int korScore) {
		this.korScore = korScore;
	}

	public int getEngScore() {
		return engScore;
	}

	public void setEngScore(int engScore) {
		this.engScore = engScore;
	}

	public int getMathScore() {
		return mathScore;
	}

	public void setMathScore(int mathScore) {
		this.mathScore = mathScore;
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public int getRank() {
		return rank;
	}

	public void setRank(int rank) {
		this.rank = rank;
	}

	//3.List에 저장된 데이터는 '학번의 오름차순(초기상태)'으로 정렬할 수 있는 내부정렬 기준을 구현한다.(내부정렬 기준은 하나만 만들수 있음)
	@Override
	public int compareTo(Student stu) {
		return ((Integer)this.getId()).compareTo(stu.getId());//내가 가지고 있는 id랑 stu에서 가져온 id를  내부정렬로 비교하기
	//return Integer.compare(this.getNum().std.getNum());
	}

	@Override
	public String toString() {//toString은 값을 뽑아 올것
		return "Student [id=" + id + ", name=" + name + ", korScore="
				+ korScore + ", engScore=" + engScore + ", mathScore="
				+ mathScore + ", total=" + total + ", rank=" + rank + "]";
	}

	
}

//4.그리고, 총점의 역순으로 정렬하는데 총점이 같으면 이름의 오름차순으로 정렬이 될 수 있는 외부 정렬 기준 클래스를 작성한다.
//총점을 기준(내림차순) 만약에 총점이 같으면 이름을 기준으로 오름차순 - 외부정렬 클래스
class totalDESC implements Comparator<Student>{//외부정렬은 다른곳에서 가져와야되서 클래스로 따로 빼줌
// 정렬 두가지가 있어야되는데, 내부정렬같은경우 안에 이미 1가지 그러면 밖에 1가지만 가져오면되고, 외부정렬은 안에 아무것도없어가지고 2개를 가져와야됨
	@Override
	public int compare(Student stu1, Student stu2) {//외부정렬은 안에 아무것도없어가지고 2개를 가져와야됨
		// 0 양수 음수
		int result = ((Integer)stu1.getTotal()).compareTo(stu2.getTotal())*-1;
		if(result == 0) result = stu1.getName().compareTo(stu2.getName());//총점이 같을 경우에는 이름순으로 오름차순으로 정렬
		return result;//0이면 값이 같을때 변화 없음(-1이면 변하고 )
		
	}
	
}

/*4.
 * class totalDESC implements Comparator<Student>{
	public int compare(Student stu1, Student stu2) {
		if(std1.getTotal() == std2.getTotal()){
			return std.getName().compareTo(std.getName());
		}else{
			return Integer.compare(std1.gerTotal(), std2.getTotal())
		}
	}
}*/



//등수를 구하는 메서드(sem)
/*public class StudentTest{
	public void setRanking(List<Student> sidList){
		for(Student std1 : stdList){//기준 데이터를 구하는 반복문
			int rank =1;//처음에는 1등으로 설정해 놓고 시작
			for(Student std2 : stdList){//비교 대상을 구하는 반복문
				//기분보다 비교 대상이 더 크면 rank값을 증가시킨다.
				if(std1.getTotal() < std2.getTotal()){
					rank++;
				}
			}
			
			//구해진 등수를 Student객체의 rank변수에 저장한다.
			std1.setRank(rank);
		}
	}
	
}*/


//2.이 Student객체는 List에 저장하여 관리한다.
public class StudentTest {

	public static void main(String[] args) {
		ArrayList<Student> studentList = new ArrayList<>();
		studentList.add(new Student(1,"이중호",100,60,50));//번호, 이름, 국어,영어,수학 점수
		studentList.add(new Student(4,"홍길동",10,30,50));
		studentList.add(new Student(8,"김충신",90,60,50));
		studentList.add(new Student(7,"이순신",70,60,40));
		studentList.add(new Student(6,"강아지",40,20,30));
		studentList.add(new Student(3,"장독대",60,60,60));
		studentList.add(new Student(2,"이민정",30,30,30));
		
		
		
		System.out.println("아직 정렬전");
		/*
		for(int i=0; i<studentList.size(); i++){
			studentList.get(i).setTotal(studentList.get(i).getKorScore()+studentList.get(i).getEngScore()+studentList.get(i).getMathScore());
			System.out.println(studentList.get(i));
		}*/
		//studentList <- ArrayList에다가 Student 박아 넣는거야
		//stu <- Student
		
		for(Student stu: studentList){
			stu.setTotal(stu.getTotal());
			System.out.println(stu);
		}
		
		System.out.println("---------------------------------------");
		Collections.sort(studentList);
		System.out.println("내부정렬, 학번을 기준으로, 오름차순(초기값)");
		for(int i=0; i<studentList.size(); i++){
			System.out.println(studentList.get(i));
		}
		
		System.out.println("---------------------------------------");
		Collections.sort(studentList, new totalDESC());
		System.out.println("외부정렬, 총점을 기준으로 내림차순, 총점이 같은경우 이름을 기준으로 오름차순");
		for(int i=0; i<studentList.size(); i++){
			System.out.println(studentList.get(i));
		}
		
		
		System.out.println("---------------------------------------");
		for(int i=0; i<studentList.size(); i++){
			studentList.get(i).setRank(i+1);
			System.out.println(studentList.get(i));
		}
		
	}
}