본문 바로가기

LECTURE/# java basic

[초급 JAVA]예제-학생 시험 성적 평균 & 석차 입력/출력 프로그램

반응형

 예제-학생 시험 성적 평균 & 석차 입력/출력 프로그램

By Commin September 29, 2016

 

Programming

RankingPro.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

package array;

   

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

   

/*

 * Ranking Program Exam

 * develope by commin

 * 

 * 어떤 프로그램을 만들것인가?

 * 5명의 학생의 정보(이름),점수(국어,영어,수학)를 입력 받아 평균을 내고 석차를 구하여 출력하는 프로그램.

 * 

 * 주요 기술

 * 배열,제어문,java 입출력,메서드

 * 

 */

public class RankingPro {

    public static void main(String[] ar) throws IOException {

        // source

        int student_size = 5;// 학생수

        int subject_size = 3;// 과목 수

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

        String names[] = new String[student_size];// 5명의 학생이름

        String subject[] = new String[] { "국어""영어""수학" };

        double scores[][] = new double[student_size][subject_size + 1];// 1:국어,2:영어,3:수학,4:평균

        int rank[] = new int[student_size];

   

        // 학생 이름 입력 받기. 인자로 BufferedReader와 학생 수변수를 넣었네요.

        names = inputName(in, student_size);

   

        // 각 학생의 점수 입력

        System.out.println("*** 입력 받은 이름 ***");

        for (int i = 0; i < names.length; i++) {

            System.out.println((i + 1+ ". " + names[i]);

        }

   

        for (int i = 0; i < scores.length; i++) {

            System.out.println(names[i] + "의 점수입력!!");

            for (int j = 0; j < scores[i].length; j++) {

                if (j == subject_size) {

                    double total = 0;

                    for (int z = 0; z < subject_size; z++) {

                        total += scores[i][z];

                    }

                    scores[i][j] = total / subject_size;// scores 마지막 공간에 평균을 넣습니다.

                    break;// 가장 가까운 반복문을 빠져나가도록 하는 예약어입니다.

                }

                System.out.print(subject[j] + " > ");

                double score = Double.parseDouble(in.readLine());

                scores[i][j] = score;

            }

        }

   

        // 석차 구하기

        // 1번학생과 나머지를 비교하여1번학생보다 점수가 낮으면 상대방 래크를 +1, 2번학생이 점수가낮으면 2번학생 랭크+1

        // 2번학생과 나머지를 비교하여 2번학생보다 점수가 낮으면 상대방 래크를 +1, 2번학생이 점수가낮으면 2번학생 랭크+1

        // 마지막학생까지 바복하면 최종적으로 석차가 구해집니다.

        for (int i = 0; i < student_size; i++) {

            rank[i] = 1;// 일단 모든 랭크 값을 1로 초기화 합니다. 최초에는 모든 학생들이 1등입니다.

        }

   

        for (int i = 0; i < student_size; i++) {

            double standard_student_score = scores[i][subject_size];//기준학생점수

   

            for (int j = i; j < student_size; j++) {

                double compare_student_score = scores[j][subject_size];//비교학생점수

                if (standard_student_score < compare_student_score) {

                    rank[i]++;//기준학생이 점수가 납으므로 기준학생의 랭크를 +1해줍니다.

                } else if (standard_student_score > compare_student_score) {

                    rank[j]++;//비교학생의 점수가 낮으므로 비교학생의 랭크를 +1해줍니다.

                }

            }

        }

   

        showTable(names, subject, scores, rank);

   

    }

   

    // 입력한 내용을 테이블로 보여주는 메서드입니다. 여러번 사용될지도 모르는 기능은 이렇게 메서드로 만들어놓는 것이 편합니다.

    public static void showTable(String[] names, String[] subject, double[][] scores, int[] rank) {

        System.out.println();

        System.out.print("이름   | ");

        for (int i = 0; i < subject.length + 1; i++) {

            if (i == subject.length) {

                System.out.print("평균|   ");

                System.out.print("석차|   ");

                break;

            }

   

            System.out.print(subject[i] + "| ");

   

        }

        System.out.println();

   

        for (int i = 0; i < names.length; i++) {

            System.out.print(names[i] + " |");

            for (int j = 0; j < scores[i].length; j++) {

                System.out.print(scores[i][j] + "| ");

            }

            System.out.println(rank[i]+"|");

        }

        System.out.println();

    }

   

    // 메서드를 사용해보기위해 억지로 넣었습니다.

    // 클래스인 BufferedReader도 매개변수로 넣을 수 있습니다.

    public static String[] inputName(BufferedReader inint size) {

        String[] names = new String[size];

   

        for (int i = 0; i < size; i++) {

            System.out.println("학생 이름을 입력 해주세요 <" + (size - i) + ">");

            try {

                System.out.print("이름  > ");

                String name = in.readLine();

                names[i] = name;

            } catch (IOException e) {

                System.out.println("err : IOException");

                i--;// 오류가 나게되면 프로그램을 종료시킬것이 아니라 i를 하나 줄여서 다시 같은자리에 입력 받는것이 더 유연한프로그램입니다.

                continue;

            }

        }

        System.out.println();// 한줄개행

        return names;

    }

   

}

Colored by Color Scripter

cs



안녕하세요 commin 입니다. 이번 포스팅은 저번 배열 포스팅에서 말씀드린대로 간단한 예제를 만들면서 지금까지 배웠던 내용을 복습하고 실습하는 시간을 가져보도록 하겠습니다.
프로그램을 만들 때 저는 크게 두가지를 생각하고 만듭니다. 

첫째, 어떤프로그램을 만들것인가? 
둘째, 프로그램을 만들기 위한 주 기술은 무엇인가? 

프로그램의 주제와 목적을 정하고 프로그램을 구현하기 위해 어떤 기술을 사용해야하는지 생각하는겁니다. 이번에 저와같이 실습할 예제는 학생들의 이름과 시험점수를 입력 받아서 각 학생의 평균과 석차를 구해 출력하는 프로그램을 만드는겁니다. 이제 확실히 무엇을 만들지 아셨다면 위 소스를 참고하여 자신이 직접 구현해봅시다. 예제포스팅은 각 기능단위별로 끊어서 설명하겠습니다.

20-26
프로그램에 필요한 자원을 초기화하는 영역입니다.

이 프로그램을 만들기 위해 필요한 자원은 학생들 이름, 과목이름, 과목별 점수,평균 그리고 석차가 있습니다. 저는 학생의 수를 5명으로 정해 놓고 프로그래밍을 했지만 학생수와 과목수를 변수 student_size와 subject_size에 담음으로써 추후에 학생수나 과목수를 입력 받도록 하여 바꿀 수 있도록 여지를 두었습니다. 이것은 이 글을 보는 여러분이 재 수정을 하면서 구현해보세요. 제가 지은 변수명을 보시면 이변수가 무엇을 담을 변수인지 알 수 있습니다. 이렇게 변수명을 지을때 변수명이 길어지더라도 변수의 역할을 의미하는 단어들의 조합으로 만드는 것이 추후에 소스 관리할때 유리합니다. 


107-125
학생들의 이름을 입력 받는 메서드입니다.
선언한 변수들이 모두 지역변수(메서드 안에서만 생존하는 변수)로 선언되어있기 때문에 조금은 어색한 메서드일 수 있지만, 메서드를 복습하기 위해 그리고 메서드의 매개변수에는 여러가지를 넣을 수 있다는것을 보여드리기 위해 이렇게 코딩했습니다. 29라인을 보시면 inputName()메서드를 호출하고 메서드로부터 return 받은 데이터를 names라는 String 배열에 넣습니다. 여기서 중요한 점은 메서드가 return하는 데이터의 유형과 그것을 담는 변수의 유형과 같아야 한다는 점이죠. 실제로 inputName()의 return 데이터는 String[] 이고 names의 자료형 역시 String[] 입니다. 틀리면 이클립스에서 알아서 안된다고 빨간줄 그어주니까 걱정마세요^^
메서드 내용은 딱히 어려운건 없습니다. BufferedReader는 매개변수로 받지 않고 메서드안에서 또 생성해서 쓰면되지만 리소스관리 차 만든건 재활용하는 편이 좋아 받은거구요, String[]을 새로만들어서 for문을 이용해 학생 수만큼 반복하여 학생의 이름을 입력받았습니다. 그리고 끝에 return해서 데이터를 돌려주었구요. 


37-52
학생들의 점수를 입력받고 그 점수로 평균까지 구해서 score[] 안에 넣는 영역입니다.

for문 안에 for가 무려 2개가 더 쓰였습니다. 그렇다고 미리 겁내지마세요. 하나하나 보면 쉽습니다. 일단 첫번째 for문은 scores의 길이만큼(scores.length)반복하도록 설정했습니다. scores는 이중배열이므로 scores[student_size][subject_size+1]의뜻을 해석해보면 학생 수 (5)만큼 줄을 서고 한줄에 과목수에 1을 더한값(4)만큼 서라. 라는 의미입니다. 그러니 scores배열의 크기는 학생수와 같습니다. (첫번째 대괄호가 전체크기고 뒤 대괄호가 한줄의 크기라고 생각하세요.) 그리고 밑에 "names[i]의 점수입력"은 방금 입력받은 학생들의 이름이 names 배열에 0분터 4까지 순서대로 담아져있으니 학생의 이름이 순서대로 출력되겠죠. 그리고 두번째 for문을 보시면 scores[i].length 만큼 반복하도록 설정하였습니다. i 가 0일때로 생각해보면 scores[0].lenth는 0번째 줄의 크기입니다. 방금전에 한줄의 크기는 몇이라고 했죠? 그렇습니다. 과목수 + 1 입니다. +1 을 한건 모든 과목의 점수를 받고 마지막에는 평균값을 넣어줄려고 한겁니다. if문에는 j의 값이 subject_size(3)과 같은지 묻습니다. i는0이니까 넘어갑니다. subject[j]는 과목이름을 출력합니다. j가 0부터 3까지 증가하는데 과목은 0,1,2에 국영수가 차례대로 넣어져있습니다. j가 3이되면 위에 if문에서 걸릴테니 범위를 초과할일은 없겠네요. 그리고 double형의 score 변수를 만들고 값을 입력 받는데 , 모르시는 코딩이 나왔습니다. 당황하지마세요. 

double score = Double.parseDouble(in.readLine())은 in.readLine으로 입력받은 String 값을 Double형으로 변환 시켜주는 역할을 합니다. 이밖에도 Integer.parseInt(String str) , Float.parseFloat(String str) 등 등 String 값을 변환시켜주는 메소드들을 java에서는 기본으로 제공해줍니다. 이참에 외워두세요 ^^ 

이어서 scores[0][0]에 score를 대입하고 다시 for문은 돕니다. 아직 i값은 0 그대로이고 j의 값이 +1되어 1이 됩니다. 그럼 scores[0][1]에 score값을 넣게되죠. 뜻을 풀어서 말씀드리자면, scores[0][0] = 0번째줄(첫번째학생)의 0번째로 줄선 데이터(첫과목(국어)의점수)가 score의 값이다. 입니다.

이렇게 두번째 for문이 반복하다가 j 가 3이될때 if문안으로 들어갑니다. if문 안에 for문에서 scores[0][0]~scores[0][2]를 더해서 total변수에 넣고 그값을 scores[0][3]안에 넣으면 scores배열 0번째 줄에는 국어,영어,수학,평균 이 순서대로 입력되게됩니다. 이과정이 학생수(5)만큼 반복되면 모든 학생들의 점수와 평균이 scores 배열안에 입력되게됩니다. 

62-73

석차를 구해서 rank 배열에 순서대로 입력합니다. rank 배열의 순서는 student배열의 순서와 대응됩니다.

또한번 이중배열을 쓰고 다중 for문을 썼습니다. 이중배열과 다중배열은 아주 찰떡궁합과도 같은 관계라고 생각하셔도 무방합니다. 지금까지 보셨으면 이제 익숙해졌겠지요? 그럼 석차구하는 방법을 설명드리겠습니다. 석차를 구하는방법은 여러가지가있는데 그 중에 대표적인 방법으로 설명드리겠습니다. 다섯명의 학생이있다고 치면, 제일먼저 첫번째 학생의 점수를 기준으로 두고 나머지 학생들과 점수를 비교합니다. (이때 최초 석차는 5명 모두 1등입니다. ) 첫번째학생과 두번째학생의 점수를 비교해서 첫번째 학생의 점수가 더 높다면 두번째 학생의 석차는 +1이 되어 증가하게됩니다. 만약 두번째학생의점수가 더 높다면 첫번째학생의 석차를 +1하여 증가시킵니다. 이 과정을 반복하여 마지막학생까지 비교를 했다면 두번째학생을 기준으로 두고 나머지학생과 비교합니다. 이 때, 이미 비교를 한 첫번째학생과는 비교할 필요가없으므로 두번째학생은 세번째,네번째, 다섯번째 학생과 비교합니다. 이런과정을 반복합니다. 모든 과정이 끝나면 최종적으로 학생들의 석차가 나오게됩니다. 

이걸 소스로 옮기면 위 소스처럼 됩니다. 그렇다면 소스가 이해되실거라 생각합니다. 여기서 두번째 for문에 선언부를 봐주세요. int j = i 로 되어있죠? 이걸 int j = i+1로 바꾸셔도됩니다. 그러면 비교할때 자기자신을 비교안하게됩니다. 지금은 자기자신도 비교하게되는데, 값이 같을 때는 따로 처리한 부분이없으니 그냥넘어가게되니 프로그램에는 크게지장없습니다. 

밑에는 결과물입니다. 


반응형