[JS] 프로그래머스 수식 최대화

bepyan·2021년 4월 19일
1

알고리즘

목록 보기
4/16

문제 링크

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

내 해결법

전위표기식 -> 후위 표기식 -> 계산

const getPostfix = (expression, priority) => {
    const st = [], cal = [];
    var val = 0;
    for (var c of expression) {
        if ('0' <= c && c <= '9') {
            val = 10 * val + Number(c);
            continue;
        }
        cal.push(val);
        val = 0;

        while (st.length && priority[st[st.length - 1]] >= priority[c])
            cal.push(st.pop());
        st.push(c);
    }
    if (val) cal.push(val)

    return cal.concat(st.reverse());
}
const getAnswer = (cal) => {
    const nums = [];
    cal.forEach(v => {
        if (!isNaN(v)) return nums.push(v);

        const b = nums.pop();
        const a = nums.pop();
        switch (v) {
            case '+':
                return nums.push(a + b);
            case '-':
                return nums.push(a - b);
            case '*':
                return nums.push(a * b);
        }
    })
    return nums.pop();
}
function solution(expression) {
    const getMax = () => {
        var res = getAnswer(getPostfix(expression, priority));
        res = res > 0 ? res : -res
        return max > res ? max : res;
    }
    var priority = { '+': 0, '-': 1, '*': 2 }
    var max = getMax();
    priority = { '+': 1, '-': 0, '*': 2 }
    max = getMax();

    priority = { '+': 0, '-': 2, '*': 1 }
    max = getMax();
    priority = { '+': 1, '-': 2, '*': 0 }
    max = getMax();

    priority = { '+': 2, '-': 1, '*': 0 }
    max = getMax();
    priority = { '+': 2, '-': 0, '*': 1 }
    max = getMax();

    return max;
}

문제해결에 급급하다보니.. 좀 아쉬운 부분이 많다.

코드 정리

const getPostfix = (expressionArr, priority) => {
    const st = [], cal = [];
    
    expressionArr.forEach(item => {
        if (!isNaN(item)) 
            return cal.push(Number(item));

        while (st.length && priority[st[st.length - 1]] >= priority[item])
            cal.push(st.pop());
        st.push(item);
    })
    return cal.concat(st.reverse());
}
function solution(expression) {
    const priors = [
        { '+': 0, '-': 1, '*': 2 },
        { '+': 0, '-': 2, '*': 1 },
        { '+': 1, '-': 0, '*': 2 },
        { '+': 2, '-': 0, '*': 1 },
        { '+': 1, '-': 2, '*': 0 },
        { '+': 2, '-': 1, '*': 0 },
    ]
    const calculate = {
        '+': (a, b) => a + b,
        '-': (a, b) => a - b,
        '*': (a, b) => a * b
    }
    return Math.max(...priors.map(prior => {
        const nums = [];
        getPostfix(expression.split(/(\D)/), prior).forEach(v => {
            if (!isNaN(v)) return nums.push(v);

            const b = nums.pop();
            const a = nums.pop();
            nums.push(calculate[v](a, b));
        })
        return Math.abs(nums.pop());
    }));
}
  • 정규식으로 연산자, 숫자 분리
  • Math의 abs, max을 활용
  • switch문을 {}로 대체

다른 방법

function solution(expression) {
    const priors = [
        ['-', '*', '+'],
        ['-', '+', '*'],
        ['*', '-', '+'],
        ['*', '+', '-'],
        ['+', '-', '*'],
        ['+', '*', '-']
    ]
    const calculate = {
        '+': (a, b) => a + b,
        '-': (a, b) => a - b,
        '*': (a, b) => a * b
    }
    return Math.max(...priors.map(prior => {
        const arr = expression.split(/(\D)/);
        for (let op of prior) {
            while (arr.includes(op)) {
                const idx = arr.indexOf(op);
                const cal = arr.slice(idx - 1, idx + 2);
                const res = calculate[op](Number(cal[0]), Number(cal[2]));
                arr.splice(idx - 1, 3, res);
            }
        }
        return Math.abs(arr[0]);
    }))
}
  1. 배열 인덱스 순서대로 우선순위가 높음
  2. 연산자 중심으로 양옆 숫자를 가져와 연산하고 결과를 삽입
  3. 우선운위대로 연산를 모두 삭제시킴
profile
쿠키 공장 이전 중 🚛 쿠키 나누는 것을 좋아해요.

0개의 댓글