1) 과제: 최소한의 수정으로 아래 조건 만족시키
@Test
@DisplayName("100 + (10 + 5) == 25")
void t25() {
assertThat(Calc.run("100 + (10 + 5)")).isEqualTo(115);
}
2) 문제점
수정전 코드는 괄호가 식의 중간부터 열려있는 부분에 대한 처리가 안되어있었다.
3) idea
최대한 기존 코드의 로직을 유지한체 변경하기 위하여 기존의 로직 위에 괄호가 시작되는 위치에 따라 splitpoint의 값을 변경하는 로직을 추가한다.
수정부분

상기 수정으로 테스트 케이스는 통과하게 되었다.
1) 과제: 아래 조건 만족시키기
@Test
@DisplayName("-(8 + 2) -(7 + 3) + 5 == 105")
void t30() {
assertThat(Calc.run("-(8 + 2) -(7 + 3) + 5")).isEqualTo(105);
}
2) 수정 전 후 코드 (좌 수정전 우 수정 후)



3) 문제점
①번에서 하고 있는 처리는, 만약에 문자열이 -(로 시작 되고 있는 경우 -를 뺀 나머지 문자열에 -1을 붙여주는거다.
이 처리에 있는 문제점은 만약에 -(로 열린 괄호가 문자열 중간에 닫혔을 경우에도 문자열 뒷부분에 -1을 붙여준다는 점이다.
②번에서 하고 있는 처리는 괄호 바깥 쪽에있는 +나 *위치를 돌려주는 것이다. 이 처리의 문제점은 괄호 바깥의 -에 대해서는 고려되지 않았다는 점이다.
4) idea
① 식의 어느 위치에 -(가 올 지 모르고 어느위치에서 괄호가 닫힐지 모른다는게 기존의 문제였기 때문에, 식 도중에 어느 위치에서든 -(가 열리고, 닫힐 때 닫힌자리 위에 " * -1"을 삽입한 문자열을 반환하는 메소드를 새로 만들었다.
②기존 로직에 -위치를 돌려주는 로직을 더해줘도 되지만, 괄호가 어떤식으로 묶여있든 처리가 쉽도록 하기 위해 메소드를 추가로 만들었다.
해당 메서드의 기능은 가장 처음으로 오는 ')'의 위치를 찾고 (중복 괄호인 경우 가장 처음으로 오는 ')'은 가장 안쪽에 위치한 ')'일 것이다.) 그 ')'과 쌍을 이루는 '('을 찾은 뒤에 그 안쪽에 있는 연산을 재귀처리를 통해 먼저 처리해 준다.
이렇게 가장 안쪽에 있던 괄호부터, 괄호 단위로 연산처리를 반복하여, 괄호연산부터 순차적으로 연산처리를 할 수 있도록 한다.