2023-12-28 (15일차) - 계산기 만들기, 재귀함수

·2023년 12월 28일

📅 2023-12-28, 15일차

🧮계산기 만들기

(20 + 20) + 20 == 60
(10 + 20) * 3 == 90
  • 괄호로 시작하는 테스트케이스는 괄호가 있는 인덱스 찾아서 잘 쪼개지만
10 + (10 + 5) == 25
  • 괄호로 시작하지 않고 중간에 괄호가 나오는 테스트 케이스 같은 경우에는 쪼개지 못한다. 모든 테스트케이스가 괄호로 시작 할 수는 없다는 경우의 수를 생각하고, 나눌 수 있는 더하기 기호를 TRUE/FALSE 사용하여 찾아보기. 만약 FALSE라면 plan B로, 나눌 수 있는 곱하기 기호 찾기.
public static int run(String exp) { // 10 + (10 + 5)
 
	boolean needToSplit = exp.contains("(") || exp.contains(")");

 	if (needToSplit) {  // 800 + (10 + 5)

      int splitPointIndex = findSplitPointIndex(exp);

      String firstExp = exp.substring(0, splitPointIndex);
      String secondExp = exp.substring(splitPointIndex + 1);

      char operator = exp.charAt(splitPointIndex);

      exp = Calc.run(firstExp) + " " + operator + " " + Calc.run(secondExp);

      return Calc.run(exp);


private static int findSplitPointIndexBy(String exp, char findChar) {
    int bracketCount = 0;

    for (int i = 0; i < exp.length(); i++) {
      char c = exp.charAt(i);

      if (c == '(') {
        bracketCount++;
      } else if (c == ')') {
        bracketCount--;
      } else if (c == findChar) {
        if (bracketCount == 0) return i;
      }
    }
    return -1;
  }

private static int findSplitPointIndex(String exp) {
   int index = findSplitPointIndexBy(exp, '+');

   if (index >= 0) return index;

   return findSplitPointIndexBy(exp, '*');
 }

재귀함수

  • 함수 내부에서 ‘자기 자신을 호출’하는 함수. 이를 통해서 함수가 자신을 반복적으로 호출하면서 원하는 결과를 도출할 수 있다.

재귀함수를 사용한 factorial 구하기

  • Factorial 함수에 4라는 인자값을 매개변수로 받아서
    그 4를 재료로 사용하여 함수 내부 실행 후 나온 결과 값을, 함수를 처음 호출하고 끝난 자리(이 예시에서는 출력문)에 리턴.
  • factorial이라는 함수내에서 factorial이라는 함수로 호출 중
    • 재귀호출
	public static void main(String[] args) {
		System.out.println("4! : " + Factorial(4));
	}
    
	private static int Factorial(int n) {
		if (n == 0 || n == 1) {
			return 1;
		}
        // 재귀호출
		return n * Factorial(n - 1);
	}
    
    // 출력결과
    // 4! : 24

3항연산자를 사용한 재귀함수 factorial 구하기

  • 리턴. n이 1보다 크다면. 뭘해라? n 곱하기 나 자신인 Factorial이라는함수에다 (n - 1) 값을 넘겨줘. 그렇지 않다면 1을 반환해.
	private static int Factorial(int n) {

		return (n > 1) ? n * Factorial(n -1) : 1
	}

재귀호출 되는 구조를 쉽게 파악하기 위해 recursionDebug 활용

  • 출력문을 사용하여 실행문이 돌 때마다 몇번 도는지, 돌때마다 테스트케이스가 어떻게 연산을 하는지 변수와 출력문을 활요하여 눈으로 확인 할 수 있다.
  • boolean debug를 false에서 true로 바꿔주면 debug모드를 수동으로 키는 것 처럼 테스트케이스 연산을 추적하여 보여준다.
public static boolean debug = false;
public static int runCallCount = 0;

public static int run(String exp) {
	runCallCount++;
 
	if(recursionDbug) {
		System.out.printf("exp(%d) : %s\n", runCallCount, exp)
    }
}

대입과 비교를 동시에 하기

  • 말 그대로, 대입하고 비교하기
 while ((pos = findNegativeCaseBracket(exp)) != null) {
      exp = changeNegativeBracket(exp, pos[0], pos[1]);
    }

IntelliJ 의 plugin - Sequence Diagram

  • 인텔리제이에서 Sequence Diagram이라는 플러그인을 다운받을 수 있다
  • Sequence Diagram은 어떤 순서로 어떤 객체와 어떻게 상호작용했는지 보여주는 diagram이다. 이걸 사용하면 시스템이 어떤 시나리오로 움직이고 있는지 파악하기 쉽다.
profile
hello world

0개의 댓글