자바

다양한 방법으로 사칙연산 계산기 만들기

하이자바 2025. 2. 27. 20:41

1.  클래스 없이 사칙 연산 계산기

2. 클래스를 활용한 사칙 연산 계산기

3. Enum, 제네릭, 람다 스트림을 이용한 계산기 만들기

 

 

요구사항 

1. 사칙연산과 제곱근, 제곱, 괄호 사용이 가능한 계산기

2. 사용자 인터페이스 방식은 콘솔 기반으로 제작

 

예외처리 및 체크 리스트

1. 사용자가 쉽게 해당 기능을 사용할 수 있는가? 프로그램 실행 시 식 입력이라는 문구와 exit 종료 그리고 계산 가능한 사칙연산 기호 표기 그리고 예외에 대한 오류 문구 출력

2. 잘못된 입력에 대한 예외 처리를 하였는가? ex) )(+3, asdasd 등 계산기에 적합하지 않은 식 순서나 문자에 대한 예외 처리

3. double에 따른 소수점 값 문제 해결 ex) 10/3에 대한 double 결과 값 10.3333335와 같은 미세한 값 오류에 대한 예외 처리

4. 각종 입력에 대한 예외 소수의 사칙연산, 정수의 사칙연산, 0나누기, 결과값에 따른 정수, 소수 표기

 

 

로직

식 입력 ex) 5*10+15/30 -> 리스트에 담아서 한 자리씩 스플릿 -> 10,20,30,100과 같은 숫자는 한자리씩 담으면

일의 자리의 정수가 됨 여기서 조건을 추가, 연산 기호가 있으면 하나의 값으로 보자, 수와 연산을 각 리스트에 나눠 저장

-> 값 추출 후 괄호 생각하여 계산 수행 (연산자 우선 계산해야함 중위표기 -> 후위표기) 여기서 어차피 중위에서 후위로 바꿀건데

숫자, 연산 분리 리스트 만들 필요가 없다고 느낌 -> 하나의 리스트로 통합 후 변환 수행 -> 변환 식 계산을 진행해야함 -> 스택에서

숫자 입력 시 푸시하도록 하고 연산자가 나오는 경우 그 연산자에 맞게 계산식을 통해 pop 실행 -> 마지막 계산결과 과정에서

몫과 나머지는 0으로 나누거나 값을 구할 수 없음 -> 플래그를 하나 만들어서 예외 발생 시 true, 그리고 결과에서 !error라는 조건을 통해 예외가 발생하지 않은 결과값만 출력 -> 결과 값이 정수인지 실수인지를 판단하여 10.0과 같은 정수값을 10으로 표기되도록 설정

 

 

트러블 슈팅

괄호를 어떻게 인식을 시키고 계산에 적용시킬까?

- 괄호는 연산 순위는 가장 높게 잡아야 하고, 괄호의 닫힘 방향이 일치해야 제대로 된 계산식이 성립됨

- 일반적인 중위식 (20+3)/2 와 같은 식은 괄호에 대한 조건을 만들기 힘듦

- 중위식을 후위식으로 변환

 

해결법

1. 먼저 입력에서 괄호에 대한 예외 처리를 하였음

if(input.contains("()")){
    System.out.println("빈 괄호 허용하지 않음");
    continue;
}
if(input.matches(".*\\)\\d.*")){
    System.out.println("닫는 괄호 뒤 숫자 바로 못 옴");
    continue;
}
int open = 0;
int close = 0;
for (char c : input.toCharArray()) {
    if (c == '(') open++;
    else if (c == ')') close++;
}

if (open != close) {
    System.out.println("괄호 개수 에러");
    continue;
}
Stack<Character> valid = new Stack<>();
boolean invalid = false;

for(char c: input.toCharArray()) {
    if(c == '('){
        valid.push(c);
    }
    else if(c == ')'){
        if(valid.isEmpty()){
            invalid = true;
            break;
        }
        valid.pop();
    }
}
if(invalid){
    System.out.println("괄호 순서가 잘못됨");
    continue;
}

 

괄호를 담는 valid 스택, 괄호 순서 오류용 flag인 invalid 생성 후 입력 문자열 검사

만약 ( 이면 push

)인데 스택이 비어있으면 짝이 안맞으므로 오류 아니면 () 한쌍을 없앰

그리고 invalid가 true가 되면 오류 발생하는 로직 작성

 

다음과 같이 작성하여 클래스를 사용하지 않고 계산기를 만들었다.

 

위와 같은 로직을 이용해 2,3번 조건의 계산기를 만들고자 한다.

하지만 구현 방식의 차이이기에 나머지는 깃허브 코드로 대체한다. 

 

https://github.com/donghee-develop/cal_pj