• [Lv2] 수식 최대화

    2021. 7. 1.

    by. 창고

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

     

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

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

    programmers.co.kr

    function solution(expression) {
        var answer = Number.MIN_SAFE_INTEGER;
        let priorityArr = [ // 연산자의 서로 다른 우선 순위 조합
            ['*', '+', '-'],
            ['+', '-', '*'],
            ['-', '*', '+'],
            ['+', '*', '-'],
            ['*', '-', '+'],
            ['-', '+', '*'],
        ];
        let expressArr = [];
        let copiedArr = expressArr.slice() // 복사본 하나 만들어 놓기
    
        // expression : "100+200+300"을 expressArr : [100,'+',200,'+',300]으로 변환
        for (let i = 0; i < expression.length; i++) {
            let str = '';
            let c = expression[i];
    
            if (!isNaN(c)) {
                str += c;
                while (!isNaN(expression[i+1])) {
                    i++;
                    str += expression[i];
                }
                expressArr.push(Number(str));
            } else {
                expressArr.push(c);
            }
        }
    
        // 연산자 우선 순위 모든 경우의 수에 대해서 진행
        for (let i = 0; i < priorityArr.length; i++) {
            expressArr = copiedArr.slice(); // 이중 for문과 while을 돌리면 expressArr이 원형을 유지하지 못하기 때문에, 복사하여 원형을 복구
    
            // 연산자 우선 순위 경우의 수들 중 한 개에서 가장 우선 순위가 높은 연산자부터(j===0) 가장 우 순위가 낮은 연산자(j===2)까지 차례차례 연산
            for (let j = 0; j < priorityArr[i].length; j++) {
                let temp = []; // 계산을 도와줄 임시 Array
                let operator = priorityArr[i][j]; // 연산자를 가져옴. 예를들어, ['+', '-', '*']에서 j=0이면 +를, j=2이면 *를 가져옴.
                while (1) { // 목표는 expressArr의 모든 원소가 사라질 때 까지 진행함.
                    let firstNum = expressArr.shift(); // 첫 번째 숫자 가져옴
                    let compOper = expressArr.shift(); // 첫 번째는 숫자이므로, 두 번째는 반드시 연산자임
    
                    if (!compOper) { // 연산자가 안나온 경우, expressArr에 남은 숫자가 없음
                        temp.push(firstNum); // temp에 넣고 while문 탈출
                        break;
                    }
    
                    if (compOper === operator) { // 우선 순위에 해당하는 연산자인 경우, 
                        let secondNum = expressArr.shift(); // 연산자 뒤의 숫자를 꺼내서
                        switch (compOper) { // 계산을 진행한다.
                            case '+': 
                                expressArr.unshift(firstNum + secondNum); // 계산한 결과는 다시 expressArr에 넣는다.
                                break;
                            case '-':
                                expressArr.unshift(firstNum - secondNum);
                                break;
                            case '*':
                                expressArr.unshift(firstNum * secondNum);
                                break;
                        }
                    } else {
                        temp.push(firstNum); // 우선 순위에 해당하는 연사자가 아니면,
                        temp.push(compOper); // 임시 배열에 넣는다.
                    }
                }
    
                if (temp.length === 1) { // 임시 배열의 길이가 1인 경우, 최종 값을 갖고 있는 상태
                    answer = Math.max(answer, temp[0] < 0 ? -temp[0] : temp[0]);
                }
                expressArr = temp.slice(); // 임시 배열의 길이가 1이 아닌 경우, temp를 expressArr에 복사하고 다음 연산자 제거
            }
        }
        return answer;
    }

    '알고리즘 > 프로그래머스' 카테고리의 다른 글

    다리를 지나는 트럭  (0) 2021.07.15
    [Lv2] 순위 검색  (0) 2021.07.04
    [Lv2] 배달  (0) 2021.06.26
    [Lv2] 124 나라 숫자  (0) 2021.06.21
    [Lv3] 입국심사  (0) 2021.06.16

    댓글