View

https://programmers.co.kr/learn/courses/30/lessons/67257

 

코딩테스트 연습 - 수식 최대화

IT 벤처 회사를 운영하고 있는 라이언은 매년 사내 해커톤 대회를 개최하여 우승자에게 상금을 지급하고 있습니다. 이번 대회에서는 우승자에게 지급되는 상금을 이전 대회와는 다르게 다음과

programmers.co.kr

 

문제 설명

기본적인 연산자 우선 순위는 *, +, - 지만 이 문제에서는 연산자 우선순위를 마음대로 지정할 수 있다.

수식이 주어지고, 연산자 우선 순위를 지정해서 수식의 절대값이 가장 큰 값을 출력하라.

 

입출력 예

expression                                                                                                                                 result

"100-200*300-500+20" 60420
"50*6-3*2" 300

 

 

문제 해결 아이디어

먼저 정규표현식으로 숫자와 연산자를 구분해 준다. 매번 정규표현식이 필요할 때마다 검색해서 쓰는 편이라 공부가 필요할 듯하다...

처음에는 연산자 우선순위를 조합으로 뽑아서 계속 계산하려고 했는데 생각해 보니까 3! = 6개밖에 없어서 그냥 배열에 넣어 놓고 반복문을 돌았다.

연산자 우선순위마다 수식을 계산해 준다. 현재 순위에 해당하는 연산자가 연산자 배열에 있는지 확인 후에, 있으면 계산해서 배열을 갱신해 준다. JS의 indexOf() 메서드를 사용한다. 배열에 해당 연산자가 여러 개 있을 수 있기 때문에 없을 때까지 (indexOf() 값이 -1이 될 때까지) 반복문을 돌아 준다.

수식은 어차피 중위표현식이므로 숫자 배열 갱신은 indexOf()로 찾은 index + 1 값으로 해 주면 된다.

 

완성된 코드

function solution(expression) {
  var answer = Number.MIN_VALUE;

  // 계산 함수
  const cal = (a, b, op) => {
    if (op === "*") return a * b;
    else if (op === "-") return a - b;
    else return Number(a) + Number(b);
  };

  // 숫자로 된 문자열 1개 이상인 문자열
  const reg1 = /\d+/;
  const reg2 = /[*+-]/;

  let nums = expression.split(reg2);
  let ops = expression.split(reg1);
  // 공백이 하나씩 추가돼서 제거해줌

  ops.pop();
  ops.shift();

  // 우선순위로 나올 수 있는 후보들
  const cands = [
    ["+", "*", "-"],
    ["+", "-", "*"],
    ["*", "+", "-"],
    ["*", "-", "+"],
    ["-", "*", "+"],
    ["-", "+", "*"],
  ];

  cands.forEach((cand) => {
    nums = expression.split(reg2);
    ops = expression.split(reg1);
    ops.pop();
    ops.shift();

    cand.forEach((i) => {
      // 해당 연산자가 ops에 없으면 굳이 안 해도 됨
      if (ops.indexOf(i) === -1) {
        return;
      } else {
        let index = ops.indexOf(i);

        // 해당 연산자가 여러개 있을 수도 있으니까 반복문
        while (index !== -1) {
          // nums index 위치에 계산결과 넣고 뒤에꺼는 없애줌
          nums[index] = cal(nums[index], nums[index + 1], i);
          // index + 1부터 1개의 원소 삭제
          nums.splice(index + 1, 1);
          ops.splice(index, 1);
          index = ops.indexOf(i);
        }
      }
    });
    answer = Math.max(Math.abs(nums[0]), answer);
  });
  return answer;
}
Share Link
reply
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30