Java/개념

11장 문제풀이

태감새 2023. 1. 2. 20:51

11-1. 정수 집합의 교집합, 차집합, 합집합을 구하는 코드를 완성하라.

	cha = (ArrayList) list1.clone();    // 차집합에 list1 복제
        Iterator it1 = list1.iterator();

        while(it1.hasNext()){               // list1 하나씩 반복문
            Object tmp = it1.next();        // it1.next 를 tmp에 저장
            if (list2.contains(tmp)){       // 만약 tmp가 list2에 있다면
                kyo.add(tmp);               // 교집합에 저장, 차집합 제거
                cha.remove((tmp));
            } else{
                hap.add(tmp);               // list2와 안겹치는거 합집합에 저장
            }
        }

        hap.addAll(list2);                  // list요소 합집합으로 복사

- 답지랑 다름

차집합 : list1 복제 후 중복되는 값 제거

합집합 : list1 에서 중복되는 값 빼고 입력 후 list2값 모두 입력

교집합 : 중복되는 값만 입력

그림 설명

전체코드

더보기
import java.util.*;

public class Main extends Object {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList<Object>();
        ArrayList list2 = new ArrayList<Object>();
        ArrayList kyo = new ArrayList(); // 교집합  A n B
        ArrayList cha = new ArrayList(); // 차집합  A - B
        ArrayList hap = new ArrayList(); // 합집합  A u B

        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(4);
        list2.add(3);
        list2.add(4);
        list2.add(5);
        list2.add(6);

        cha = (ArrayList) list1.clone();    // 차집합에 list1 복제
        Iterator it1 = list1.iterator();

        while(it1.hasNext()){               // list1 하나씩 반복문
            Object tmp = it1.next();        // it1.next 를 tmp에 저장
            if (list2.contains(tmp)){       // 만약 tmp가 list2에 있다면
                kyo.add(tmp);               // 교집합에 저장, 차집합 제거
                cha.remove((tmp));
            } else{
                hap.add(tmp);               // list2와 안겹치는거 합집합에 저장
            }
        }

        hap.addAll(list2);                  // list요소 합집합으로 복사

        System.out.println("list1="+list1);
        System.out.println("list2="+list2);
        System.out.println("kyo="+kyo);
        System.out.println("cha="+cha);
        System.out.println("hap="+hap);

    }
}

11-2. 다음 코드의 실행결과는?

import java.util.*;

public class Main extends Object {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(3);
        list.add(6);
        list.add(2);
        list.add(2);
        list.add(2);
        list.add(7);

        HashSet set = new HashSet(list);    // 중복제거, 순서없음 3,2,6,7
        TreeSet tset = new TreeSet(set);    // 순서형성. 2,3,6,7
        Stack stack = new Stack();
        stack.addAll(tset);                 // 2,3,6,7 순으로 스택에 저장

        while(!stack.empty())
            System.out.println(stack.pop());    // stack은 LIFO 방식이므로 7,6,3,2 순으로 출력
    }
}

- 출력

7

6

3

2

 


11-3. 비용이 가장 많이 드는 작업은?

ArrayList의 길이(요소의 개수)를 n이라고 가정

 

a. 첫 번째 요소 삭제. ( n )

첫 번째 요소를 제외한 모든 요소(n-1 개)를 복사해서 옮겨야 하고 삭제(n)를 포함하면  n-1 + 1 = n의 비용이 든다.

b. 마지막 요소 삭제. ( 1 )

마지막 요소만 지우면 배열의 이동이 없으므로 삭제만하면 된다.

c. 마지막에 새로운 요소 추가.

마지막에 값을 추가해도 배열의 이동이 없으므로 추가의 비용만 지불하면 된다.

d. 중간에 새로운 요소 추가. ( n/2 + 1 )

중간에 값을 저장하면 배열을 반 나눠서 뒷부분(n/2)만 이동하고 추가(1)하므로 n/2 + 1 의 비용이 든다.

 

정답 : a

 


11-4. LinkedList에 11개의 요소를 추가하였을 때 접근 시간이 가장 오래걸린 것은?

- 틀림

정답 : 여섯 번째 요소

이유는 LinkedList는 실제로 이중 원형 연결리스트이기 때문이다.

일반적인 연결리스트
이중 원형 연결리스트

일반적인 연결리스트는 형태가 선형이다. 끝이 존재하고 마지막 값은 null이다.

원형 연결리스트는 마지막 노드가 첫 번째 노드를 가리키는 연결방식이다.

이중 원형 연결리스트는 노드에 세 가지의 값을 저장한다. 본인값, 이전값, 다음값.

예를들어 5번째 노드는 4번째, 5번째, 6번째 값을 저장하고 있는 것이다.

연결된 리스트 (좌,우 어디든 이동이 가능하다.)

각 인덱스에는 위에서 언급한대로 세 가지 값이 저장되어있고 어느 방향으로든 이동이 가능하다.

그래서 중간에 있는 값에 도달하는데 가장 많은 시간이 걸린다.

 


11-5. Student클래스가 Comparable인터페이스를 구현하도록 변경 후 이름이 기본 정렬기준이 되도록 하라.

    class Student impements Comparable{
    
    /* ..... */

    @Override
    public int compareTo(Object o) {
        if(o instanceof Student){
            int thisch = (int)name.charAt(0);
            int ch = (int)((Student) o).name.charAt(0);

            return thisch-ch;
        }else{
            return 0;
        }
    }

- 답지랑 다름.

Student클래스에 Comparable을 구현해주고 compareTo 메서드를 오버라이딩한다.

자신(this)의 이름(name) 첫글자의 정수값과 매개변수의 정수값을 구하여 뺀 값을 반환한다.

전체코드

더보기
import java.util.*;

class Student implements Comparable{
    String name;
    int ban;
    int no;
    int kor, eng, math;

    public Student(String name, int ban, int no, int kor, int eng, int math) {
        this.name = name;
        this.ban = ban;
        this.no = no;
        this.kor = kor;
        this.eng = eng;
        this.math = math;
    }

    int getTotal(){
        return kor+eng+math;
    }

    float getAverage(){
        return (int)((getTotal()/3f)*10+0.5)/10f;
    }

    public String toString(){
        return name +","+ban +","+no +","+kor+","+eng +","+math+","+getTotal() +","+getAverage();
    }

    @Override
    public int compareTo(Object o) {
        if(o instanceof Student){
            int thisch = (int)name.charAt(0);
            int ch = (int)((Student) o).name.charAt(0);

            return thisch-ch;
        }else{
            return 0;
        }
    }
}

public class Main extends Object {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(new Student("홍길동",1,1,100,100,100));
        list.add(new Student("남궁성",1,2,90,70,80));
        list.add(new Student("김자바",1,3,80,80,90));
        list.add(new Student("이자바",1,4,70,90,70));
        list.add(new Student("안자바",1,5,60,100,80));

        Collections.sort(list);
        Iterator it = list.iterator();

        while(it.hasNext())
            System.out.println(it.next());
    }
}

11-6. 성적 평균의 범위별로 학생수를 센다. TreeSet이 학생들의 평균을 기준으로 정렬하도록 compare 메서드와 평균의 범위를 주면 그 범위의 학생 수를 반환하는 getGround() 완성하라.

    static int getGroupCount(TreeSet tset, int from, int to){
        int cnt = 0;
        for (Object student : tset) {
            float averageValue = ((Student)student).getAverage();
            if(from <= averageValue && averageValue < to){
                cnt += 1;
            }
        }
        return cnt;
    }

	/* ..... */
    
    TreeSet set = new TreeSet(new Comparator() {
        @Override
        public int compare(Object o1, Object o2) {
            float iv1 = ((Student)o1).getAverage();
            float iv2 = ((Student)o2).getAverage();
            return (int)(iv1-iv2);
        }
        });

- 답지랑 다름

- getGroupcount 

수를 카운트 할 cnt 값을 0으로 초기화하고 tset의 요소를 하나씩 뽑아서 값을 비교한다.

averageValue 변수에 평균값을 저장하고 범위 내에 있을 경우 cnt 값에 1을 더해준다.

모든 요소를 확인했으면 cnt 값을 반환한다.

- TreeSet

두 객체를 Student로 형변환 후 평균을 구하여 변수(iv1, iv2)에 입력한다.

두 수의 차를 반환한다.

전체코드

더보기
import java.util.*;

class Student implements Comparable{
    String name;
    int ban;
    int no;
    int kor, eng, math;

    public Student(String name, int ban, int no, int kor, int eng, int math) {
        this.name = name;
        this.ban = ban;
        this.no = no;
        this.kor = kor;
        this.eng = eng;
        this.math = math;
    }

    int getTotal(){
        return kor+eng+math;
    }

    float getAverage(){
        return (int)((getTotal()/3f)*10+0.5)/10f;
    }

    public String toString(){
        return name +","+ban +","+no +","+kor+","+eng +","+math+","+getTotal() +","+getAverage();
    }

    @Override
    public int compareTo(Object o) {
        if(o instanceof Student){
            Student tmp = (Student) o;

            return name.compareTo((tmp.name));
        }else{
            return -1;
        }
    }
}

public class Main extends Object {
    static int getGroupCount(TreeSet tset, int from, int to){
        int cnt = 0;
        for (Object student : tset) {
            float averageValue = ((Student)student).getAverage();
            if(from <= averageValue && averageValue < to){
                cnt += 1;
            }
        }
        return cnt;
    }

    public static void main(String[] args) {
        TreeSet set = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                float iv1 = ((Student)o1).getAverage();
                float iv2 = ((Student)o2).getAverage();
                return (int)(iv1-iv2);
            }
        });

        set.add(new Student("홍길동",1,1,100,100,100));
        set.add(new Student("남궁성",1,2,90,70,80));
        set.add(new Student("김자바",1,3,80,80,90));
        set.add(new Student("이자바",1,4,70,90,70));
        set.add(new Student("안자바",1,5,60,100,80));

        Iterator it = set.iterator();

        while(it.hasNext())
            System.out.println(it.next());

        System.out.println("[60~69] :"+getGroupCount(set,60,70));
        System.out.println("[70~79] :"+getGroupCount(set,70,80));
        System.out.println("[80~89] :"+getGroupCount(set,80,90));
        System.out.println("[90~100] :"+getGroupCount(set,90,101));
    }
}

11-7. BanNoAscending 클래스를 완성하여 ArrayList에 담긴 Student 인스턴스틀이 반과 번호로 오름차순이 되도록 정렬하라. (반이 같은 경우 번호로 비교)

    @Override
    public int compare(Object o1, Object o2) {
        Student s1 = (Student) o1;
        Student s2 = (Student) o2;

        if(s1.ban == s2.ban){
            // 반이 같은 경우
            return s1.no - s2.no;
        }
        else{
            // 반이 다른 경우
            return s1.ban - s2.ban;
        }
    }

두 객체를 Stduent로 형변환 한 뒤 두 객체의 반 비교.

같으면 번호의 차를 반환하고 다르면 반의 차를 반환한다.

전체코드

더보기
import java.util.*;

class Student{
    String name;
    int ban;
    int no;
    int kor, eng, math;

    public Student(String name, int ban, int no, int kor, int eng, int math) {
        this.name = name;
        this.ban = ban;
        this.no = no;
        this.kor = kor;
        this.eng = eng;
        this.math = math;
    }

    int getTotal(){
        return kor+eng+math;
    }

    float getAverage(){
        return (int)((getTotal()/3f)*10+0.5)/10f;
    }

    public String toString(){
        return name +","+ban +","+no +","+kor+","+eng +","+math+","+getTotal() +","+getAverage();
    }
}

class BanNoAscending implements Comparator {

    @Override
    public int compare(Object o1, Object o2) {
        Student s1 = (Student) o1;
        Student s2 = (Student) o2;

        if(s1.ban == s2.ban){
            // 반이 같은 경우
            return s1.no - s2.no;
        }
        else{
            // 반이 다른 경우
            return s1.ban - s2.ban;
        }
    }
}

public class Main extends Object {

    public static void main(String[] args) {
        ArrayList list = new ArrayList();

        list.add(new Student("이자바",2,1,70,90,70));
        list.add(new Student("안자바",2,2,60,100,80));
        list.add(new Student("홍길동",1,3,100,100,100));
        list.add(new Student("남궁성",1,1,90,70,80));
        list.add(new Student("김자바",1,2,80,80,90));

        Collections.sort(list,new BanNoAscending());

        Iterator it = list.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }


    }
}

11-8.총점(total)과 전교등수(schoolRank)를 저장하기 위한 인스턴스 변수를 추가. 기본 정렬을 총점의 내림차순으로 정렬. 총점으로 학생의 전교등수 계산 후 전교등수로 오름차순.

    public int compareTo(Object o) {
        return((Student)o).getTotal() - this.getTotal();
    }

     /*  .......... */

    static void calculateSchoolRank(List list){
        Collections.sort(list);

        int prevRank = -1;
        int prevTotal = -1;
        int length = list.size();

        for (int i = 0; i < list.size(); i++) {
            Student s = (Student) list.get(i);

            if(prevTotal == s.total){
                // 동일 점수
                s.schoolRank = prevRank;
            }
            else {
                // 점수가 다른 경우
                // 오름차순으로 이미 정렬했으므로
                s.schoolRank = i + 1;
            }

            prevRank = s.schoolRank;
            prevTotal = s.total;
        }
    }

compareTo 메서드는 총합을 기준으로 내림차순이므로 객체의 총합에서 자신의 총합을 빼준다.

calculateSchoolRank 클래스에서는 리스트의 길이만큼 반복문을 돈다.

반복문에서 i값을 인덱스로하는 객체의 총합이 이전의 합과 같다면 전교등수에 이전 등수와 같은 값을 넣어준다.

그렇지 않다면 전교 등수는 인덱스(i)값의 + 1을 대입한다.

마지막에 이전 랭크와 이전 총합에 객체의 랭크와 총합을 대입해준다.

전체코드

더보기
import java.util.*;

class Student implements Comparable{
    String name;
    int ban;
    int no;
    int kor, eng, math;

    int total;
    int schoolRank;

    public Student(String name, int ban, int no, int kor, int eng, int math) {
        this.name = name;
        this.ban = ban;
        this.no = no;
        this.kor = kor;
        this.eng = eng;
        this.math = math;

        this.total = kor+eng+math;
    }

    int getTotal(){
        return kor+eng+math;
    }

    float getAverage(){
        return (int)((getTotal()/3f)*10+0.5)/10f;
    }

    public String toString(){
        return name +","+ban +","+no +","+kor+","+eng +","+math+","+getTotal() +","+getAverage()+","+schoolRank;
    }

    @Override
    public int compareTo(Object o) {
        return((Student)o).getTotal() - this.getTotal();
    }
}

public class Main extends Object {
    static void calculateSchoolRank(List list){
        Collections.sort(list);

        int prevRank = -1;
        int prevTotal = -1;
        int length = list.size();

        for (int i = 0; i < list.size(); i++) {
            Student s = (Student) list.get(i);

            if(prevTotal == s.total){
                // 동일 점수
                s.schoolRank = prevRank;
            }
            else {
                // 점수가 다른 경우
                // 오름차순으로 이미 정렬했으므로
                s.schoolRank = i + 1;
            }

            prevRank = s.schoolRank;
            prevTotal = s.total;
        }
    }

    public static void main(String[] args) {
        ArrayList list = new ArrayList();

        list.add(new Student("이자바",2,1,70,90,70));
        list.add(new Student("안자바",2,2,60,100,80));
        list.add(new Student("홍길동",1,3,100,100,100));
        list.add(new Student("남궁성",1,1,90,70,80));
        list.add(new Student("김자바",1,2,80,80,90));

        calculateSchoolRank(list);

        Iterator it = list.iterator();

        while(it.hasNext()){
            System.out.println(it.next());
        }


    }
}

11-9. 반등수(classRank) 인스턴스 추가. 반등수를 계산하고 반과 반등수로 오름차순 정렬하라.

class ClassTotalComparator implements Comparator{

    @Override
    public int compare(Object o1, Object o2) {
        Student s1 = (Student) o1;
        Student s2 = (Student) o2;

        int result = s1.ban - s2.ban;
        if (result == 0){  // same class
            return s2.total - s1.total;
        }
        else{
            return result;
        }
    }
}

     /* .......... */
     
static void calculateClassRank(List list){

        Collections.sort(list,new ClassTotalComparator());

        int prevBan = -1;
        int prevRank = -1;
        int prevTotal = -1;
        int length = list.size();

        int tmp = 0;

        for (int i = 0; i < length; i++) {
            Student s = (Student) list.get(i);

            if(prevBan != s.ban){
                s.classRank = 1;
                tmp = i;
            }
            else if(prevTotal == s.total){
                s.classRank = prevRank;
            }
            else{
                s.classRank = (i - tmp) + 1;
            }
            prevRank = s.classRank;
            prevTotal = s.total;
            prevBan = s.ban;
        }
    }

compare 메서드

반은 오름차순으로 정렬해야 하므로 s1.ban - s2.ban을 반환한다.

같은 반에서 점수는 내림차순으로 정리하므로 s2.total - s1.total을 반환한다.

calculateClassRank 클래스

ClassTotlaComparator 클래스로 정렬 후 반 등수를 부여한다.

리스트의 길이만큼 반복되고 리스트는 반은 오름차순, 같은 반에서 성적은 내림차순으로 정렬되어있다.

1. 만약 반이 다르다면 객체의 랭크를 1로 초기화하고 tmp에 i 값을 넣는다.

2. 같은 반에서 총합이 같다면 같은 랭크를 부여한다.

3. 같은 반에서 총합이 다르다면 i - tmp + 1 의 랭크를 부여한다.

4. 이전 값들을 객체의 값들로 초기화한다.

전체코드

더보기
import java.util.*;

class Student implements Comparable{
    String name;
    int ban;
    int no;
    int kor, eng, math;

    int total;
    int schoolRank;
    int classRank;

    public Student(String name, int ban, int no, int kor, int eng, int math) {
        this.name = name;
        this.ban = ban;
        this.no = no;
        this.kor = kor;
        this.eng = eng;
        this.math = math;

        this.total = kor+eng+math;
    }

    int getTotal(){
        return kor+eng+math;
    }

    float getAverage(){
        return (int)((getTotal()/3f)*10+0.5)/10f;
    }

    public String toString(){
        return name +","+ban +","+no +","+kor+","+eng +","+math+","+getTotal() +","+getAverage()+","+schoolRank+","+classRank;
    }

    @Override
    public int compareTo(Object o) {
        return((Student)o).getTotal() - this.getTotal();
    }
}

class ClassTotalComparator implements Comparator{

    @Override
    public int compare(Object o1, Object o2) {
        Student s1 = (Student) o1;
        Student s2 = (Student) o2;

        int result = s1.ban - s2.ban;
        if (result == 0){  // same class
            return s2.total - s1.total;
        }
        else{
            return result;
        }
    }
}

public class Main extends Object {
    static void calculateClassRank(List list){

        Collections.sort(list,new ClassTotalComparator());

        int prevBan = -1;
        int prevRank = -1;
        int prevTotal = -1;
        int length = list.size();

        int tmp = 0;

        for (int i = 0; i < length; i++) {
            Student s = (Student) list.get(i);

            if(prevBan != s.ban){
                s.classRank = 1;
                tmp = i;
            }
            else if(prevTotal == s.total){
                s.classRank = prevRank;
            }
            else{
                s.classRank = (i - tmp) + 1;
            }
            prevRank = s.classRank;
            prevTotal = s.total;
            prevBan = s.ban;
        }
    }

    static void calculateSchoolRank(List list){
        Collections.sort(list);

        int prevRank = -1;
        int prevTotal = -1;
        int length = list.size();

        for (int i = 0; i < length; i++) {
            Student s = (Student) list.get(i);

            if(prevTotal == s.total){
                // 동일 점수
                s.schoolRank = prevRank;
            }
            else {
                // 점수가 다른 경우
                // 오름차순으로 이미 정렬했으므로
                s.schoolRank = i + 1;
            }

            prevRank = s.schoolRank;
            prevTotal = s.total;
        }
    }

    public static void main(String[] args) {
        ArrayList list = new ArrayList();

        list.add(new Student("이자바",2,1,70,90,70));
        list.add(new Student("안자바",2,2,60,100,80));
        list.add(new Student("홍길동",1,3,100,100,100));
        list.add(new Student("남궁성",1,1,90,70,80));
        list.add(new Student("김자바",1,2,80,80,90));
        list.add(new Student("김자바1",1,2,80,80,90));
        list.add(new Student("김자바2",1,2,80,80,90));
        list.add(new Student("김자바3",1,2,80,80,90));
        list.add(new Student("안자바1",2,2,60,100,80));
        list.add(new Student("수자바",2,2,80,100,80));
        list.add(new Student("간자바",2,2,100,100,80));

        calculateSchoolRank(list);
        calculateClassRank(list);

        Iterator it = list.iterator();

        while(it.hasNext()){
            System.out.println(it.next());
        }


    }
}

11-10. 빙고판 문제 개선.

- 답지봄

해싱 알고리즘의 특성상 한 숫자가 고정된 위치에 저장된다.

그래서 ArrayList로 변경하여 shuffle 과정을 추가해야 한다.

전체 코드

더보기
import java.util.*;

public class Main extends Object {
    public static void main(String[] args) {
        Set set = new HashSet();
        int[][] board = new int[5][5];

        for(int i=0; set.size() < 25; i++) {
            set.add((int)(Math.random()*30)+1+"");
        }

        ArrayList list = new ArrayList(set);	// 추가
        Collections.shuffle(list);		// 추가

        Iterator it = list.iterator();		// list로 변경

        for(int i=0; i < board.length; i++) {
            for(int j=0; j < board[i].length; j++) {
                board[i][j] = Integer.parseInt((String) it.next());
                System.out.print((board[i][j] < 10 ? "  " : " ") + board[i][j]);
            }
            System.out.println();
        }
    }
}

11-11. HashSet에 중복카드가 저장되지 않도록 hashCode()를 오버라이딩 해라.

public int hashCode(){
        return toString().hashCode();
    }

객체의 출력값이 같더라도 객체의 주소는 다 다르므로 다르게 인식한다.

그래서 equals() 메서드와 hashCode() 메서드를 오버라이딩 해서 적절히 입력해야 한다.

위의 hashCode() 메서드는 문자열의 내용이 같으면 같은 해쉬코드를 반환하는 코드이다.

두 개의 3K는 문자열이 같으므로 같은 값으로 인식되어 중복삭제된다.

전체코드

더보기
import java.util.*;

class SutdaCard{
    int num;
    boolean isKwang;

    SutdaCard(){
        this(1,true);
    }

    public SutdaCard(int num, boolean isKwang) {
        this.num = num;
        this.isKwang = isKwang;
    }

    public boolean equals (Object obj){
        if (obj instanceof SutdaCard){
            SutdaCard c = (SutdaCard) obj;
            return num == c.num && isKwang == c.isKwang;
        }
        else{
            return false;
        }
    }

    public String toString(){
        return num + (isKwang ? "K":"");
    }
    public int hashCode(){
        return toString().hashCode();
    }
}

public class Main extends Object {
    public static void main(String[] args) {
        SutdaCard c1 = new SutdaCard(3,true);
        SutdaCard c2 = new SutdaCard(3,true);
        SutdaCard c3 = new SutdaCard(1,true);

        HashSet set = new HashSet();
        set.add(c1);
        set.add(c2);
        set.add(c3);

        System.out.println(set);
    }
}

11-12. 등급과 점수를 계산하는 registerJokbo()와 게임 참가자의 점수를 계산해서 반환하는 getPoint()를 완성하라.

       jokbo.put("KK",4000);
       jokbo.put(10+""+10,3100);
       jokbo.put(9+""+9,3090);
       jokbo.put(8+""+8,3080);
       jokbo.put(7+""+7,3070);
       jokbo.put(6+""+6,3060);
       jokbo.put(5+""+5,3050);
       jokbo.put(4+""+4,3040);
       jokbo.put(3+""+3,3030);
       jokbo.put(2+""+2,3020);
       jokbo.put(1+""+1,3010);
       jokbo.put(1+""+2,2060);
       jokbo.put(2+""+1,2060);
       jokbo.put(1+""+4,2050);
       jokbo.put(4+""+1,2050);
       jokbo.put(1+""+9,2040);
       jokbo.put(9+""+1,2040);
       jokbo.put(1+""+10,2030);
       jokbo.put(10+""+1,2030);
       jokbo.put(4+""+10,2020);
       jokbo.put(10+""+4,2020);
       jokbo.put(4+""+6,2010);
       jokbo.put(6+""+4,2010);

     /* .......... */

    if(c1.isKwang && c2.isKwang){
           result = (Integer) jokbo.get("KK");
       }
       else if(!(jokbo.get(c1.num+""+c2.num) == null)){
           result = (Integer) jokbo.get(c1.num+""+c2.num);
       }
       else{
           result = (c1.num + c2.num) % 10 + 1000;
       }

       p.point = result.intValue();
       return result.intValue();

족보를 그대로 HashMap에 넣어준다. 

둘 다 광이면 KK값의 value를 반환하고 족보에 값이 있으면 그 값의 value를 반환한다.

족보에 공식이 없으면 일반식을 통하여 값을 반환한다.

-- 나는 deck.pick()에서 계속 오류가 나서 결과를 확인하지 못했다.

전체코드

더보기
import java.util.*;

class SutdaDeck{
   final int CARD_NUM = 20;
   SutdaCard[] cards = new SutdaCard[CARD_NUM];

   int pos = 0;
   HashMap jokbo = new HashMap();

   SutdaDeck(){
       for (int i = 0; i < cards.length; i++) {
           int num = i%10+1;
           boolean isKwang = i < 10 && (num==1 || num==3 || num==8);

           cards[i] = new SutdaCard(num,isKwang);
       } // 카드 입력
       registerJokbo();
   }

   void registerJokbo(){    // 족보 입력
       jokbo.put("KK",4000);
       jokbo.put(10+""+10,3100);
       jokbo.put(9+""+9,3090);
       jokbo.put(8+""+8,3080);
       jokbo.put(7+""+7,3070);
       jokbo.put(6+""+6,3060);
       jokbo.put(5+""+5,3050);
       jokbo.put(4+""+4,3040);
       jokbo.put(3+""+3,3030);
       jokbo.put(2+""+2,3020);
       jokbo.put(1+""+1,3010);
       jokbo.put(1+""+2,2060);
       jokbo.put(2+""+1,2060);
       jokbo.put(1+""+4,2050);
       jokbo.put(4+""+1,2050);
       jokbo.put(1+""+9,2040);
       jokbo.put(9+""+1,2040);
       jokbo.put(1+""+10,2030);
       jokbo.put(10+""+1,2030);
       jokbo.put(4+""+10,2020);
       jokbo.put(10+""+4,2020);
       jokbo.put(4+""+6,2010);
       jokbo.put(6+""+4,2010);
   }


   int getPoint(Player p){
       if(p==null) return 0;

       SutdaCard c1 = p.c1;
       SutdaCard c2 = p.c2;

       Integer result = 0;

       if(c1.isKwang && c2.isKwang){
           result = (Integer) jokbo.get("KK");
       }
       else if(!(jokbo.get(c1.num+""+c2.num) == null)){
           result = (Integer) jokbo.get(c1.num+""+c2.num);
       }
       else{
           result = (c1.num + c2.num) % 10 + 1000;
       }

       p.point = result.intValue();
       return result.intValue();
   }

   SutdaCard pick() throws Exception{
       SutdaCard c = null;

       if(0 <= pos && pos < CARD_NUM){
           c = cards[pos];
           cards[pos++] = null;
       }else{
           throw new Exception("남아있는 카드가 없습니다.");
       }
       return c;
   }

   void shuffle(){
       for(int x=0; x < CARD_NUM * 2; x++) {
           int i = (int) (Math.random() * CARD_NUM);
           int j = (int) (Math.random() * CARD_NUM);

           SutdaCard tmp = cards[i];
           cards[i] = cards[j];
           cards[j] = tmp;
       }
   }
}   //SutdaDeck

class Player{
    String name;
    SutdaCard c1;
    SutdaCard c2;
    int point;//카드의 등급에 따른 점수 -새로 추가

    public Player(String name, SutdaCard c1, SutdaCard c2) {
        this.name = name;
        this.c1 = c1;
        this.c2 = c2;
    }

    @Override
    public String toString() {
        return "["+name+"]"+ c1.toString() +","+ c2.toString();
    }
}


class SutdaCard{
    int num;
    boolean isKwang;

    public SutdaCard(){
        this(1,true);
    }

    public SutdaCard(int num, boolean isKwang) {
        this.num = num;
        this.isKwang = isKwang;
    }

    @Override
    public String toString() {
        return num + (isKwang ? "K":"");
    }
}

public class Main extends Object {
    public static void main(String[] args) {
        SutdaDeck deck = new SutdaDeck();

        deck.shuffle();
        Player p1 = new Player("타짜", deck.pick(), deck.pick());
        Player p2 = new Player("고수", deck.pick(), deck.pick());

        System.out.println(p1+" "+deck.getPoint(p1));
        System.out.println(p2+" "+deck.getPoint(p2));
    }
}

11-13. Player들의 점수를 계산하고 점수가 제일 높은 사람을 출력하는 코드. 내림차순이 되도록 코드를 완성하라.

        TreeMap rank = new TreeMap(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if( o1 instanceof  Player && o1 instanceof  Player){
                    Player c1 = (Player) o1;
                    Player c2 = (Player) o2;
                    return c2.point - c1.point;
                }
                return -1;
            }
        });

o1, o2의 다형성 여부를 확인하고 Player로 형변환 뒤 내림차순이므로 c2.point - c1.point 값을 반환해준다.

 


11-14. 성적 처리 기능을 완성하라.

while(true){
    String input = s.nextLine();
    int num = Integer.parseInt(input);

    if(0 < num && num < 4)
        return num;
    else
        System.out.println("메뉴를 잘못 선택하셨습니다. 다시 입력해주세요.");
}

    /* .......... */
    
while (true){
    System.out.print(">>");

    try{
        String input = s.nextLine().trim();

        if (!input.equalsIgnoreCase("q")){
            Scanner s2 = new Scanner(input).useDelimiter(",");
            record.add(new Student(s2.next(),s2.nextInt(),s2.nextInt(),s2.nextInt(),s2.nextInt(),s2.nextInt()));
            System.out.println("잘입력되었습니다. 입력을 마치려면 q를 입력하세요.");
        }
        else{
            return ;
        }
    } catch (Exception e){
        System.out.println("입력 오류입니다. 이름, 반, 번호, 국어성적, 영어성적, 수학성적'의 순서로 입력하세요.");
    }
}

- 답지 봄

첫 번째 while문

값을 입력받고 그 값이 1~3이면 그 번호를 반환하고 아니면 오류 문구를 출력한다.

두 번째 while문

값을 입력받고 그 값이 q면 공백을 반환하고 그렇지않으면 입력받은 값을 ,를 기준으로 구분한다.

그리고 그 값을 매개변수로 하는 Student 객체를 만들고 그 객체를 record에 저장한다.

만약 입력값을 구분하는 과정에서 오류가 발생하면 catch문으로 이동해 재입력을 요구한다.

전체코드

더보기
import java.util.*;

class Student implements Comparable{
    String name;
    int ban;
    int no;
    int kor, eng, math;

    int total;
    int schoolRank;
    int classRank;

    public Student(String name, int ban, int no, int kor, int eng, int math) {
        this.name = name;
        this.ban = ban;
        this.no = no;
        this.kor = kor;
        this.eng = eng;
        this.math = math;

        this.total = kor+eng+math;
    }

    int getTotal(){
        return kor+eng+math;
    }

    float getAverage(){
        return (int)((getTotal()/3f)*10+0.5)/10f;
    }

    public String toString(){
        return name +","+ban +","+no +","+kor+","+eng +","+math+","+getTotal() +","+getAverage()+","+schoolRank+","+classRank;
    }

    @Override
    public int compareTo(Object o) {
        return((Student)o).getTotal() - this.getTotal();
    }
}

public class Main extends Object {
    static ArrayList record = new ArrayList();
    static Scanner s = new Scanner(System.in);

    public static void main(String[] args) {
        while(true){
            switch(displayMenu()){
                case 1:
                    inputRecord();;
                    break;
                case 2:
                    displayRecord();
                    break;
                case 3:
                    System.out.println("프로그램을 종료합니다.");
                    System.exit(0);
            }
        }   //while
    }

    static int displayMenu(){
        System.out.println("**************************************************");
        System.out.println("* 성적 관리 프로그램 *");
        System.out.println("**************************************************");
        System.out.println();
        System.out.println(" 1. 학생성적 입력하기 ");
        System.out.println();
        System.out.println(" 2. 학생성적 보기");
        System.out.println();
        System.out.println(" 3. 프로그램 종료 ");
        System.out.println();
        System.out.print("원하는 메뉴를 선택하세요.(1~3) : ");

        int menu = 0;

        while(true){
            String input = s.nextLine();
            int num = Integer.parseInt(input);

            if(0 < num && num < 4)
                return num;
            else
                System.out.println("메뉴를 잘못 선택하셨습니다. 다시 입력해주세요.");
        }
    }   // displayMenu

    static void inputRecord(){
        System.out.println("1. 학생성적 입력하기");
        System.out.println("이름,반,번호,국어성적,영어성적,수학성적'의 순서로 공백없이 입력하세요.");
        System.out.println("입력을 마치려면 q를 입력하세요. 메인화면으로 돌아갑니다.");

        while (true){
            System.out.print(">>");

            try{
                String input = s.nextLine().trim();

                if (!input.equalsIgnoreCase("q")){
                    Scanner s2 = new Scanner(input).useDelimiter(",");
                    record.add(new Student(s2.next(),s2.nextInt(),s2.nextInt(),s2.nextInt(),s2.nextInt(),s2.nextInt()));
                    System.out.println("잘입력되었습니다. 입력을 마치려면 q를 입력하세요.");
                }
                else{
                    return ;
                }
            } catch (Exception e){
                System.out.println("입력 오류입니다. 이름, 반, 번호, 국어성적, 영어성적, 수학성적'의 순서로 입력하세요.");
            }
        }
    }   //inputRecord

    static void displayRecord(){
        int koreanTotal = 0;
        int englishTotal = 0;
        int mathTotal = 0;
        int total = 0;
        int length = record.size();

        if(length > 0){
            System.out.println();
            System.out.println("이름 반 번호 국어 영어 수학 총점 평균 전교등수 반등수");
            System.out.println("====================================================");

            for (int i = 0; i < length; i++) {
                Student student = (Student)record.get(i); System.out.println(student);
                koreanTotal += student.kor;
                mathTotal += student.math;
                englishTotal += student.eng;
                total += student.total;
            }

            System.out.println("====================================================");
            System.out.println("총점: "+koreanTotal+" "+englishTotal+" "+mathTotal+" "+total);
            System.out.println();
        } else{
            System.out.println("====================================================");
            System.out.println(" 데이터가 없습니다.");
            System.out.println("====================================================");
        }
    }   //displayRecord
}

'Java > 개념' 카테고리의 다른 글

(java.lang) String 클래스  (0) 2023.01.13
(java.lang) Object 클래스  (0) 2023.01.13
7장 문제풀이  (0) 2022.12.25
Ch5. 배열  (0) 2022.12.06
Ch.4 조건문과 반복문  (0) 2022.12.06