js 프로그래머스 수식 최대화

이명진·2024년 11월 15일
0

코드카타

목록 보기
73/74

문제 요약

식이 주어지는데 연산자와 피연산자가 함께 있는 string이다.
연산자는 +,-, 가 나오는데 기본 연산처럼 푸는게 아니라 우선순의 연산자를 구한다.
기본 연산은
먼저 계산이지만
+를 먼저 계산할수도 있고 -를 먼저 계산할수도 있고 *를 먼저 계산할수 있다.

이렇게 우선순위를 계산한 결과중 절대값을 구해서 가장 큰 값을 리턴하면 된다.

문제 풀이

카카오 인턴쉽 문제인데 그냥 간단하게 적어두면 될것을 문제를 길게해서 읽고 이해 하는데 시간이 조금 걸린것 같다.
카카오 이런데는 문제를 왜이렇게 길게 내는지 모르겠다. 간단하게 그냥 내고 예시만 많이 만들어 주지 ..

첫 시도

첫 시도때는 숫자와 연산자를 분리하여 두개의 배열을 만들었다.
그리고 우선 연산자를 구해줘야 하는데 이게 조합 방법으로 방법에는 팩토리얼 방법이 적용되었다.
3가지 연산자가 나오면 3! 안나오면 2! 조합 문제로 생각하여 이를 어떻게 풀까 고민고민하면서
이중 포문으로 순서를 변경해줄까 생각하다가 생각해보니 차피 가장 많아 봤자 6가지 밖에 안되기 때문에

그냥 전체 조합 을 모두 작성해주고 전체 조합을 다 돌리도록 하였다.

그런 다음에 연산자 모음 배열에서 조합에 맞을 경우 연산을 해줬는데 연산을 사용하면 연산배열에서 제거를 해주고
사용한 숫자 들도 숫자 배열에서 제거해주고 연산 한 결과를 넣어줘야 하는데 이러면 속도측면에서 늦어질게 분명했다.
두개의 배열을 넣고 빼고 넣고 수정하고 해야 했기 때문에 머리도 아프고 시간 초과 걸릴것 같아서 이 방법이 아닌듯 싶었다.

두번째 시도

두번째는 문제를 보면서 생각하다가 그냥 한배열에서 관리하는것을 떠올라서
그냥 숫자와 연산자를 한배열에 넣어두고 temp라는 배열에 순서대로 넣는 방법을 사용했다.
1. 전체 모음 배열에서 하나씩 빼고 temp배열에 넣어준다.
2. 만약 연산자 이면서 우선순위 연산자와 같을 때 temp에 넣어둔 것을 pop해서 빼주고 계산하고 다시 temp에 넣어준다.
3. 만약 전체 연산자 값이 1개가 남았을때 절대값으로 판정해주고 클 때 answer에 넣어준다.
이렇게 문제를 풀었는데 일단 테스트 코드들은 다 통과하였다.

하지만 제출후 채점하기에서는 몇개의 문제를 틀리는 것이었다.

문제가 뭘까 생각하면서 다른 테스트 케이들을 찾아보며 대입해보고 확인한 결과
temp에 넣으면서 계산 순서가 뒤바뀌는게 문제가 되었다.

이유는 예시로 보면 5000 -320 과 320 - 5000 과는 결과가 달라진다는 것이다.
그래서 연산하는 부분을 시작할때 전체 배열 부분에 reverse를 실행해줘서 순서대로 값을 뺄수 있도록 수정해주었다.

결과는 성공할수 있었다. 아래 내가 푼 코드를 작성해둔다.

내가 푼 코드

function solution(expression) {
  var answer = 0;
  let splits = expression.match(/(\d+|[+\-*\/])/g); //연산자와 피연산자 를 하나의 배열에 넣는다. 

// 조합 방법은 최대 6가지라서 전체를 그냥 하드 코딩해놨다 
  let cases = [
    ["*", "+", "-"],
    ["*", "-", "+"],
    ["+", "*", "-"],
    ["+", "-", "*"],
    ["-", "*", "+"],
    ["-", "+", "*"],
  ];
// 연산 함수들 
  function Sum(a, b) {
    return a + b;
  }
  function minus(a, b) {
    return a - b;
  }
  function multiply(a, b) {
    return a * b;
  }
  for (let Case of cases) {
    let splitsCopy = splits.slice(0);
    while (Case.length) {
      let temp = [];
      let target = Case.pop();
      splitsCopy = splitsCopy.reverse(); //계산이 순서대로 될수 있도록 reverse를 활용해준다. 

      while (splitsCopy.length) {
        let char = splitsCopy.pop();
        if (char === target) {
          let a = Number(temp.pop());
          let b = Number(splitsCopy.pop());

          let sum;
          if (char === "*") {
            sum = multiply(a, b);
          } else if (char === "-") {
            sum = minus(a, b);
          } else {
            sum = Sum(a, b);
          }
        
          temp.push(sum);
        } else {
          temp.push(char);
        }
      }
      splitsCopy = temp;
      if (splitsCopy.length === 1) {
	//마지막 수이기 때문에 절대값 판정을해준다. 
        let num = Math.abs(splitsCopy[0]); 
        answer = Math.max(answer, num);
        break;
      }

    }
  }

  return answer;
}

후기

처음에 봤을때 어려울것이라고 생각했는데 어느순간 내힘으로 풀수 있었다는 것에 놀라웠다.
정규식이 필요한데 정규식을 좀 알아둬야 겠다… 정규식은 지피티 도움을 받았다.
내가 이렇게 코드를 짤수 있다니 라고 생각하며 많이 성장했구나 라고 느끼게 되었다.
계속해서 문제를 풀어 나가고 있다. 지금은 3단계 조금더 생각하고 성장 할때까지 노력해야 겠다.

profile
프론트엔드 개발자 초보에서 고수까지!

0개의 댓글

관련 채용 정보