본문 바로가기

Programming/Java

명품 java programming 실습문제: 계산프로그램, 공연 예약 시스템

반응형


실습문제

5. 더하기(+), 빼기(-), 곱하기(*), 나누기(/)를 수행하는 각 클래스 Add, Sub, Mul, Div와 main() 메소드를 담은 클래스를 만들어, 계산을 수행하는 프로그램을 짜보자. main() 메소드에서는 키보드로부터 두 정수와 계산하고자 하는 연산자를 입력받아, 객체생성을 통해 연산을 수행하여 결과를 출력한다. 


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
import java.util.Scanner;
 
interface AboutCalculate{
    public void setValue(int a, int b);
    public int calculate();
}
 
class Add implements AboutCalculate{
    int a;
    int b;
    public void setValue(int a, int b) {
        this.a = a;
        this.b = b;
    }
    public int calculate() {
        int result = a + b;
        return result;
    }
}
 
class Sub implements AboutCalculate{
    int a;
    int b;
    public void setValue(int a, int b) {
        this.a = a;
        this.b = b;
    }
    public int calculate() {
        int result = a-b;
        return result;
    }
}
 
class Mul implements AboutCalculate{
    int a;
    int b;
    public void setValue(int a, int b) {
        this.a = a;
        this.b = b;
    }
    public int calculate() {
        int result = a*b;
        return result;
    }
}
 
class Div implements AboutCalculate{
    int a;
    int b;
    public void setValue(int a, int b) {
        this.a = a;
        this.b = b;
    }
    public int calculate() {
        System.out.println("모든 나눗셈 연산은 몫만 출력되어, 정수로 나타납니다.");
        int result = a/b;
        return result;
    }
}
 
 
public class CalculateProgram {
    public static void main(String[] args) {
        System.out.println("두 정수와 연산자를 입력하시오. >> ");
        Scanner scanner = new Scanner(System.in);
        int num1 = scanner.nextInt();
        int num2 = scanner.nextInt();
        char op = scanner.next().charAt(0);
        
        switch(op) {
        case '+' : 
            Add add = new Add();
            add.setValue(num1, num2);
            int addresult = add.calculate();
            System.out.println(addresult);
            break;
        
        case '-' :
            if(num1 >= num2) {
                Sub sub = new Sub();
                sub.setValue(num1, num2);
                int subresult = sub.calculate();
                System.out.println(subresult);
                break;
            }
            else {
                System.out.println("첫번째 정수가 두번째 정수보다 크거나 같아야합니다. 프로그램을 종료합니다.");
                break;
            }
            
        case '*' : 
            Mul mul = new Mul();
            mul.setValue(num1, num2);
            int mulvalue = mul.calculate();
            System.out.println(mulvalue);
            break;
            
        case '/' :
            if (num1 >= num2) {
                Div div = new Div();
                div.setValue(num1, num2);
                double divvalue = div.calculate();
                System.out.println(divvalue);
            }
            else {
                System.out.println("첫번째 정수가 두번째 정수보다 크거나 같아야합니다. 프로그램을 종료합니다.");
                break;
                
            }
        }
    }
 
cs


클래스를 이용하여 짤 수 있는 정말 간단한 문제이다. 원래 실습 문제는 인터페이스 사용을 요구하지 않았지만, 4개의 연산 클래스들이 모두 같은 메소드를 가질수 있다는 점을 이용하여, 추상메소드를 가진 인터페이스를 두고 각 클래스들이 이를 구현하면 전반적인 구조를 잡고 코드에 제약을 두기에 좋을 것이다. (가독성 측면)


이 코드의 결과는 다음과 같다.





부가적으로, 뺄셈이나 나눗셈에서 첫번째 수와 두번째 수에 대한 제약으로 경고문을 넣었고, 나눗셈에서 정수 출력에 관한 부분에도 안내문을 출력하도록 하였다. 원래 나눗셈은 몫과 나머지 모두를 출력해주고 싶었으나, 인터페이스에서 calculate()의 리턴 타입을 이미 int로 지정해놓았기 때문에 불가능했다. 그렇게 하려면 인터페이스 implement를 포기해야하는데, 통일성을 위해 그냥 int로 리턴하였다. 



6. 간단한 공연 예약 시스템을 만든다. 공연예약 시스템은 다음과 같은 조건을 만족시켜야 한다.

  1. 공연은 하루에 한 번 있다.
  2. 좌석은 S석, A석, B석 타입이 있으며 모두 10석의 좌석이 있다. (하지만 나는 출력물을 따라 S: 10석, A: 15석, B: 20석을 할당하였다.)
  3. 공연 예약 시스템의 메뉴는 "예약", "조회", "취소", "끝내기"가 있다.
  4. 예약은 한 자리만 가능하고 좌석 타입, 예약자 이름, 좌석 번호를 순서대로 입력받아 예약한다.
  5. 조회는 모든 종류의 좌석을 표시한다.
  6. 취소는 예약자 이름을 입력하여 취소한다.
  7. 없는 이름, 없는 번호, 없는 메뉴, 잘못된 취소 등에 대해서 오류 메시지를 출력하고 사용자가 다시 시도하도록 한다.


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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
import java.util.Scanner;
 
class Reserve_Seat{
    Scanner s = new Scanner(System.in);
 
    String[] sSeat = new String[10];
    String[] aSeat = new String[15];
    String[] bSeat = new String[20];
 
 
    Reserve_Seat(){ //생성자 (초기화)
        int i = 0;
        while(i<20) {
            if (i<10) sSeat[i] = "---";
            if (i<15) aSeat[i] = "---";
            bSeat[i] = "---";
            i++;
        }
    }
 
 
 
    public void show_reserve() { //조회메뉴
        System.out.print("S>> ");
        for(int i=0; i<sSeat.length; i++) {
            System.out.print(sSeat[i] + " ");
        }
 
        System.out.println();
 
        System.out.print("A>> ");
        for(int i=0; i<aSeat.length; i++) {
            System.out.print(aSeat[i] + " ");
        }
 
        System.out.println();
 
        System.out.print("B>> ");
        for(int i=0; i<bSeat.length; i++) {
            System.out.print(bSeat[i] + " ");
        }
 
        System.out.println();
    }
 
 
 
    public boolean show_oneline(int inputseats) { //지정 라인 좌석만 보여주기
        switch(inputseats) { //사용자 입력값 받은 파라미터
            case 1//s좌석 보여주기
                System.out.print("S>> ");
                for(int i=0; i<sSeat.length; i++) {
                    System.out.print(sSeat[i] + " ");
                }
                System.out.println();
                return true;
 
            case 2//a좌석 보여주기
                System.out.print("A>> ");
                for(int i=0; i<aSeat.length; i++) {
                    System.out.print(aSeat[i] + " ");
                }
                System.out.println();
                return true;
 
            case 3//b좌석 보여주기
                System.out.print("B>> ");
                for(int i=0; i<bSeat.length; i++) {
                    System.out.print(bSeat[i] + " ");
                }
                System.out.println();
                return true;
 
            default : //1~3 사이의 숫자 입력 안했을 경우
                System.out.println("잘못 입력하였습니다. 다시 입력해주세요.");
                return false;
        }
 
    }
 
 
 
    public void reservation() { //예약메뉴
        int inputseat = 0;
        String name = "";
        boolean right;
 
        while(true) {
            System.out.print("좌석구분 S<1>, A<2>, B<3> >> ");
            inputseat = s.nextInt();
 
            right = show_oneline(inputseat); //입력한 좌석 보여주기
 
            if(right == falsecontinue//다시 좌석 선택
 
 
            System.out.print("이름 >> ");
            name = s.next();
            System.out.print("번호 >> ");
            int seatnum = s.nextInt();
 
 
            try {
                switch(inputseat) {
                    case 1:
                        sSeat[seatnum-1= name;
                        break;
                    case 2:
                        aSeat[seatnum-1= name;
                        break;
                    case 3:
                        bSeat[seatnum-1= name;
                        break;
                }
 
            }
            catch(ArrayIndexOutOfBoundsException e) {
                System.out.println("없는 좌석번호입니다. 다시 입력해주세요.");
                continue;
            }
            System.out.println();
            return;
        }
 
    }
 
 
    public void del_reserve() { //예약 취소
        int delete = 0;
        boolean right;
        String delname = "";
        int count; //예약 취소 요청한 이름이 없는 이름인지 있는 이름인지 판별
 
        while(true) {
            count = 0//이 코드가 while 밖에 있으면 count가 계속 쌓여감.
            System.out.print("좌석구분 S<1>, A<2>, B<3> >> ");
            delete = s.nextInt();
 
            right = show_oneline(delete); //입력한 좌석 보여주기
 
            if(right = falsecontinue//다시 좌석 선택
 
 
            System.out.print("이름 >> ");
            delname = s.next();
 
            switch(delete) { //예약 취소
                case 1:
                    for(int i=0; i<sSeat.length; i++) {
                        if(sSeat[i].equals(delname)) {
                            sSeat[i] = "---";
                        }
                        else count += 1;
                    }
 
                    if (count == 10) {
                        System.out.println("예약되지 않은 이름입니다. 다시 시도해주세요.");
                        continue;
                    }
                    break;
 
 
                case 2:
                    for(int i=0; i<aSeat.length; i++) {
                        if(aSeat[i].equals(delname))
                            aSeat[i] = "---";
                        else count += 1;
                    }
 
                    if (count == 15) {
                        System.out.println("예약되지 않은 이름입니다. 다시 시도해주세요.");
                        continue;
                    }
 
                    break;
 
 
                case 3:
                    for(int i=0; i<bSeat.length; i++) {
                        if(bSeat[i].equals(delname))
                            bSeat[i] = "---";
                        else count += 1;
                    }
 
                    if (count == 20) {
                        System.out.println("예약되지 않은 이름입니다. 다시 시도해주세요.");
                        continue;
                    }
 
                    break;
            } //switch문
 
            System.out.println();
            return;
        }
 
    }
 
}
 
 
 
//--메인 메뉴--
public class ReserveSystem {
    public static void main(String[] args) {
        int menu = 0;
        Scanner scanner = new Scanner(System.in);
        Reserve_Seat rs = new Reserve_Seat();
 
        while(true) {
            System.out.println("************공연 예약 시스템************");
            System.out.println();
            System.out.println("예약<1>, 조회<2>, 취소<3>, 끝내기<4> ");
            System.out.println("===================================");
            System.out.print("어떤 메뉴를 이용하시겠습니까? ");
 
            menu = scanner.nextInt();
 
            switch(menu) {
                case 1 :
                    rs.reservation();
                    break;
                case 2:
                    rs.show_reserve();
                    break;
                case 3:
                    rs.del_reserve();
                    break;
                case 4:
                    System.out.println("시스템을 종료합니다.");
                    return;
 
                default:
                    System.out.println("없는 메뉴입니다. 다시 입력해주세요.");
            }
        }
    }
}
cs


코드를 구현하면서 내 코드가 너무 더럽다는 걸 너무 많이 느꼈다. 하지만 아직 개발 공부 자체도 많이 한게 아니기 때문에 리팩토링에 관한 부분은 내가 더 많은 코드를 짜보면서 배우게 될 것이라 믿는다.. 

어쨌든 이 실습문제의 코드는 다음과 같은 출력물을 내면 된다.




예외처리 : InputMismatchException

Exception in thread "main" java.util.InputMismatchException

1
2
3
4
5
6
7
public class TestError{
    public static void main(String[] args) {
        int menu = 0;
        Scanner scanner = new Scanner(System.in);
 
        menu = scanner.nextInt();
}
cs

 

위의 실습 코드에 약간의 변형을 주어 아주 간단하게 추려보았다. 코드에서는 사용자가 입력한 정수값이 menu에 저장됨을 나타내는 데, 여기서 InputMismatchException이 발생한다면 사용자는 정수가 아닌 실수나 문자열 등을 입력했기 때문이다. 

하지만 내 경우에는 올바른 범위 내의 정수만 계속 입력해줬는데도 exception 에러가 발생했다. 그 이유는 Scanner#nextInt() 메소드는 사용자 입력의 마지막 개행문자를 제거해주지 않기 때문인데, 즉, 사용자가 입력한 정수와 '엔터'까지 입력값으로 받아들였기 때문에 이 에러가 발생한 것이다. 

해결

1
2
3
4
5
6
7
public class TestError{
    public static void main(String[] args) {
        int menu = 0;
        Scanner scanner = new Scanner(System.in);
 
        menu = Integer.ParseInt(scanner.nextLine());
}
cs


이 에러에 대한 해결은 아주 간단히, 입력받은 String을 Integer#ParseInt() 를 통해 정수로 변환시켜준다. 

반응형