🔎 문제
🧩 구현과정 및 코드
개인 토글 영역에 구현 과정과 코드를 자유롭게 작성해주시면 됩니다.
사용할 데이터 구조와 풀이 방향성
적용할 알고리즘 혹은 메서드
수영
구현
코드
function solution(expression) { const answer = []; const operands = expression.match(/[0-9]+/g) // 시행착오: [+,-,*] -가 제외된다. const operators = expression.match(/[\+\-\*]/g) // 우선순위 경우의 수 const priorities = [ ["+", "-", "*"], ["+", "*", "-"], ["-", "+", "*"], ["-", "*", "+"], ["*", "+", "-"], ["*", "-", "+"], ]; // 계산 함수 const calc = (a, b, operand) => { switch(operand) { case "+": return a + b case "-": return a - b case "*": return a * b } } priorities.forEach(priority => { priority.forEach(oper => { // 우선순위를 돌면서 연산자 index를 찾는다 let i = operators.indexOf(oper) if (i !== -1) { // 연산자 index에 따라 피연산자 [i],[i+1]을 연산하고, 계산 값을 [i]와 바꾼다. operands[i] = calc(operands[i], operands[i+1], oper) // 계산 완료된 연산자, 피연산자 제거 operands.splice(i + 1, 1) operators.splice(i, 1) // 시행착오: 같은 연산자가 있는 경우 안 바꿔줬다. i = operators.indexOf(oper) } }) // 결과를 answer에 넣는다. answer.push(Math.abs(operands[0])) }) return Math.max(...answer) }
정은
구현
- 연산자의 우선순위들을 다 다르게 해서 각 케이스를 계산
- 우선순위 1위 연산자로 식 나누기
- 2를 우선순위 2위 연산자 기준으로 해서 양 옆으로 괄호로 묶어주기
- 3을 우선순위 1위 연산자로 연결해서 그 식 그대로 eval 함수로 계산한다
- 계산한 값들 중 제일 큰 값을 리턴
코드
def solution(expression): operations = [('+', '-', '*'),('+', '*', '-'),('-', '+', '*'),('-', '*', '+'),('*', '+', '-'),('*', '-', '+')] answer = [] for op in operations: a = op[0] #우선순위1 연산자 b = op[1] #우선순위2 연산자 temp_list = [] for e in expression.split(a): #우선순위 1연산자 양 옆에 있는 항들 temp = [f"({i})" for i in e.split(b)] #우선순위 2연산자 양 옆에 있는 항들을 괄호로 temp_list.append(f'({b.join(temp)})') #괄호 처리한 것을 다시 묶어줌(결국 우선순위 1 연산자 양 옆의 항들로 나뉨) answer.append(abs(eval(a.join(temp_list)))) #우선순위1 연산자를 먼저 계산한 값 return max(answer)
종혁
구현
- 연산자 우선순위의 경우의 수가 최대 6
- 경우의 수를 모두 구해놓고, 하나씩 대입해가면서 구함
코드
function solution(expression) { const pattern = /(\d+|[-*+])/g const arr = expression.match(pattern) const operators = [[ '+', '-', '*' ], [ '+', '*', '-' ], [ '-', '+', '*' ], [ '-', '*', '+' ], [ '*', '+', '-' ], [ '*', '-', '+' ]] const calculate = (a,b,op) => { switch(op){ case '*': return a * b break case '+': return a + b break case '-': return a - b break } } const result = [] for(let operator of operators){ let copy = [...arr] for(let op of operator){ let start = 0 while(copy.indexOf(op,start) > -1){ const idx = copy.indexOf(op) const result = calculate(+copy[idx-1],+copy[idx+1],op) copy.splice(idx-1,3,result) start = idx } } result.push(Math.abs(copy[0])) } return Math.max(...result) }
재웅
구현
- 연산자들을 전부 분리하여 인덱스로 계산?
"100-200*300-500+20” → [100,’-’,200,’*’,300,’-’,500,’+’,20]
코드
function solution(expression) { let answer = 0; const operations = ['*', '+', '-']; const opCases = [ ['*', '+', '-'], ['*', '-', '+'], ['+', '*', '-'], ['+', '-', '*'], ['-', '*', '+'], ['-', '+', '*'], ]; opCases.forEach((opCase) => { const opStack = []; const numStack = []; let num = ''; // 연산자 분리 for (let i = 0; i < expression.length; i++) { if (operations.includes(expression[i])) { numStack.push(Number(num)); num = ''; opStack.push(expression[i]); } else { num += expression[i]; } } numStack.push(Number(num)); // [ 100, 200, 300, 500, 20 ] // [ '-', '*', '-', '+' ] // 계산 opCase.forEach((op) => { for (let i = 0; i < opStack.length; i++) { if (opStack[i] === op) { const [num1, num2] = [numStack[i], numStack[i + 1]]; const calculated = calculate(num1, num2, op); numStack.splice(i, 2, calculated); opStack.splice(i, 1); i-=1; } } }); answer = Math.max(answer, Math.abs(numStack[0])); }); return answer; } function calculate(num1, num2, op) { switch (op) { case '*': return num1 * num2; case '+': return num1 + num2; case '-': return num1 - num2; } } // 연산자 세 개가 전부 사용된 경우, 우선순위 경우의 수는 여섯 개 // 전부 다 계산해본다는 과정하에, 재귀적으로 계산하는 알고리즘이 필요함 // 배열의 인덱스? 연산자와 숫자로 전부 나눠 // 상위 우선순위 연산자부터 찾아, 찾은 앞 뒤의 인덱스를 해당 연산자로 계산, // 세 원소를 빼고 계산한 값을 넣음
✏️ 후기
문제를 풀고 느낀 점, 막혔던 부분 혹은 개선 사항 등을 자유롭게 작성해주시면 됩니다.
수영
- 정규표현식에서 특수문자를 찾을 때는 \+ 역슬래시를 반드시 추가해야 한다. 그렇지 않으면 정규표현식(+)으로 인식한다.
정은
- eval 함수
- join과 split을 잘 활용하기
- 구현 문제 많이 풀기
종혁
재웅