프로그래밍 연습 - 스택 계산기

Zoonmy·2024년 6월 24일

간단한 스택 계산기를 만들어 보았다

🔍 구현 기능


사용한 구조체


Commands Set

Set<String> popCommands : {"POPA", "POPB", "PRINT"}
  
Set<String> registerCommands : {"ADD", "SUB", "SWAP"}
    
Set<String> pushCommands : {"PUSH0", "PUSH1", "PUSH2", "PUSH3"};
* 명령어 집합 (Commands)

- pop 메소드 [ EMPTY가 공통 ]
POPA : 스택 pop -> 레지스터 A push : empty 가능
POPB : 스택 pop -> 레지스터 B push : empty 가능
PRINT : 스택 pop -> 출력 : empty 가능

- register 메소드 [ ERROR가 공통]
ADD : 레지스터 A + 레지스터 B -> 스택 push : 레지스터 비었을 경우 = ERROR
SUB : 레지스터 A - 레지스터 B -> 스택 push : 레지스터 비었을 경우 = ERROR
SWAP : 레지스터 값들을 바꾼다 -> 레지스터가 비었을 경우 = ERROR


- push 메소드 [ OVERFLOW가 공통 ]
PUSH0, PUSH1, PUSH2, PUSH3 : 각각의 값을 스택에 push : overFlow = OVERFLOW
  • 공통되는 출력값에 따라 Set을 각각 만들어 메소드가 동작하도록 구현

Stack Class

private int[] stackValues;
private int stackPointer;

Stack() {
  this.stackValues = new int[8];
  this.stackPointer = 0;
}
  • Stack의 크기는 8
  • PUSH 연산과 POP연산 시의 OVERFLOW, EMPTY를 확인하기 위해 stackPointer 설정

Stack push()

public String push(int value) {
    if (isOverflow()) {     // -> OVERFLOW라면, "OVERFLOW" return
        return "OVERFLOW";
    }
    stackValues[stackPointer++] = value; // -> push 연산
    return "";
}
  • push하기 전, stackPointer의 값이 8인지 확인한다.
    • 8이라면, 더 이상 push 할 수 없으므로 OVERFLOW를 리턴한다.
  • stackValue[stackPointer]에 가져온 value값을 넣는다.

Stack pop()

 public int pop() {   // value 팝한 후, 포인터 감소
    return stackValues[--stackPointer];
}
  • pop 메소드 시, EMPTY처리를 하지 않은 이유
  • StackCalculator#calculatePop() 메소드에서 stack.isEmpty()를 통해 stack이 비어있는 지 먼저 확인
    • 따라서, pop 메소드에 들어오는 경우는 스택이 비어있지 않은 경우

Register Class

private int registerValue;

Register(){
    this.registerValue = -1;
}
  • register값의 초기화를 위해 -1값을 생성자에 입력

Register.isEmptyValue

public boolean isEmptyValue(){
    return registerValue == -1;
}
  • register 값이 비어있는 지 확인하기 위해 메소드 생성

🖥️ 예외 처리

입력 문자 예외 처리

  • 입력한 문자가 명령어 Set에 없을 경우에 대한 예외처리
    • InputView.checkCommands()메소드를 통해 예외 처리

레지스터 예외 처리

  • 레지스터 A, 레지스터 B가 값이 없을 경우 ADD, SUB, SWAP연산을 할 경우
    • StaclCalculator#checkRegisterHasNoValue()메소드를 통해 예외 처리

스택 예외 처리

  • 스택에서 꺼내는 POPA POPB PRINT 수행 시, 비어 있을 경우
    • stack.isEmpty()를 통해 예외 처리
  • 스택에 추가하는 ADD, SUB, PUSH 0, 1, 2, 3수행 시, 꽉 찼을 경우
    • stack.isOverflow()를 통해 예외 처리

동작 과정

String[] inputCommands = {"ADD", "PUSH3", "PUSH1", "PUSH0", "PUSH2", "PUSH1", "PUSH3", "PUSH2", "PUSH0", "PUSH3", "PUSH4"};

Command : ADD Stack : [0, 0, 0, 0, 0, 0, 0, 0] Stack Point : 0 Register A : -1 Register B : -1

Command : PUSH3 Stack : [0, 0, 0, 0, 0, 0, 0, 0] Stack Point : 0 Register A : -1 Register B : -1

Command : PUSH1 Stack : [3, 0, 0, 0, 0, 0, 0, 0] Stack Point : 1 Register A : -1 Register B : -1

Command : PUSH0 Stack : [3, 1, 0, 0, 0, 0, 0, 0] Stack Point : 2 Register A : -1 Register B : -1

Command : PUSH2 Stack : [3, 1, 0, 0, 0, 0, 0, 0] Stack Point : 3 Register A : -1 Register B : -1

Command : PUSH1 Stack : [3, 1, 0, 2, 0, 0, 0, 0] Stack Point : 4 Register A : -1 Register B : -1

Command : PUSH3 Stack : [3, 1, 0, 2, 1, 0, 0, 0] Stack Point : 5 Register A : -1 Register B : -1

Command : PUSH2 Stack : [3, 1, 0, 2, 1, 3, 0, 0] Stack Point : 6 Register A : -1 Register B : -1

Command : PUSH0 Stack : [3, 1, 0, 2, 1, 3, 2, 0] Stack Point : 7 Register A : -1 Register B : -1

Command : PUSH3 Stack : [3, 1, 0, 2, 1, 3, 2, 0] Stack Point : 8 Register A : -1 Register B : -1

[ERROR, OVERFLOW, UNKNOWN]
  • Command : ... 은 스택, 스택포인터, 레지스터 확인을 위해 추가한 메소드
String[] inputCommands = {"PUSH1", "PUSH2", "SUB", "PRINT", "POPA", "PUSH3", "POPB", "SUB", "PRINT"};

Command : PUSH1 Stack : [0, 0, 0, 0, 0, 0, 0, 0] Stack Point : 0 Register A : -1 Register B : -1

Command : PUSH2 Stack : [1, 0, 0, 0, 0, 0, 0, 0] Stack Point : 1 Register A : -1 Register B : -1

Command : SUB Stack : [1, 2, 0, 0, 0, 0, 0, 0] Stack Point : 2 Register A : -1 Register B : -1

Command : PRINT Stack : [1, 2, 0, 0, 0, 0, 0, 0] Stack Point : 2 Register A : -1 Register B : -1

Command : POPA Stack : [1, 2, 0, 0, 0, 0, 0, 0] Stack Point : 1 Register A : -1 Register B : -1

Command : PUSH3 Stack : [1, 2, 0, 0, 0, 0, 0, 0] Stack Point : 0 Register A : 1 Register B : -1

Command : POPB Stack : [3, 2, 0, 0, 0, 0, 0, 0] Stack Point : 1 Register A : 1 Register B : -1

Command : SUB Stack : [3, 2, 0, 0, 0, 0, 0, 0] Stack Point : 0 Register A : 1 Register B : 3

Command : PRINT Stack : [-2, 2, 0, 0, 0, 0, 0, 0] Stack Point : 1 Register A : 1 Register B : 3

[ERROR, 2, -2]

Gist : https://gist.github.com/pjm2571/cb4f3b662222338beb1f2cbfb26bcdaa

profile
열시미 해야쥐

0개의 댓글