티스토리 뷰

function solution(expression) {
    let l = expression.split(/([*+-])/g);
    let op = [...new Set([...expression.matchAll(/([*+-])/g)].map(x=>x[0]))];
    let f = {'*': (a,b)=>a*b, '-':(a,b)=>a-b, '+':(a,b)=>a+b};
    
    //순열
    function perm(l){
        let ret=[];
        for(let [i,x] of l.entries()){
            let rest=perm(l.slice(0,i).concat(l.slice(i+1)));
            if(!rest.length) ret.push([x]);
            else rest.reduce((r,p)=>{p.push(x); r.push(p); return r;}, ret);
        }
        return ret;
    }

    // 중위표현식 => 후위표현식
    function toPostfix(l,p){
        let s = [];
        let ret = [];
        for(let [i,x] of l.entries()){
            if(i%2==0){       //숫자
                ret.push(x);
                continue;
            }
            //연산자
            while(s.length>0){
                let top = s[s.length-1];
                if(p.get(top) < p.get(x)) break;
                ret.push(s.pop());
            }
            s.push(x);
        }

        while(s.length>0) ret.push(s.pop());
        return ret;
    }

    // 해당 우선순위 적용했을 때 계산결과 절댓값
    function calc(priority){
        let p = priority.reduce((m, o,i)=> m.set(o,i) ,new Map());
        let postfix = toPostfix(l,p);
        let s = [];
        for(let x of postfix){
            if(/\d+/.test(x)){
                s.push(+x);
                continue;
            }
            let [b,a] = [s.pop(), s.pop()];
            s.push(f[x](a,b));
        }
        return Math.abs(s[0]);
    }

    //가능한 우선순위 조합으로 모두 계산해봐서 max 값 리턴
    return perm(op).reduce((max, p)=>Math.max(max, calc(p)), 0);
}

console.log(solution("100-200*300-500+20"));
댓글
공지사항
최근에 올라온 글