https://programmers.co.kr/learn/courses/30/lessons/67257
문제 해설
경우의 수 문제이다. 모든 경우의 연산자 우선순위를 만들어 해당 연산자 우선순위를 이용해 연산을 진행하면 된다.
중위표기식으로 나타난 식을 후위 표기식으로 바꿔서 문제를 해결 했다.
경우의 수 만들기
만들 수 있는 모든 연산자 우선순위를 만들어줘야 한다. DFS를 이용해 모든 경우의 수를 만들어 줬다.
void makeAllCase(int depth) { if (depth == 3) { allCase.push_back(cntCase); }
for (int i = 0; i < 3; i++) { int cntOper = operation[i];
if (check[i] == false) { check[i] = true; cntCase[depth] = cntOper; makeAllCase(depth + 1); check[i] = false; } } }
|
연산자 우선순위를 가반으로 한 연산
가장 높은 우선순위의 연산자가 들어왔을 때
- Stack을 확인해 같은 먼저 들어온 같은 우선순위의 연산자가 있는지 확인한다.
- 같은 우선순위의 연산자가 Stack에 있는 경우
pop
해서 해당 연산을 진행한 후 지금 들어온 연산자를 push
한다.
- 없는 경우에는 Stack에
push
한다.
두번째 우선 순위가 연산자가 들어온 경우
- Stack을 확인해 우선순위가 같거나 큰 연산자가 없어질 때까지 연산을 진행한 후
pop
한다.
- Stack에 우선순위가 같거나 큰 연산자가 없을 경우에는 Stack에
push
한다.
세번째 우선 순위의 연산자가 들어온 경우
- Stack을 확인해 우선순위가 같거나 큰 연산자가 없어질 때까지 연산을 진행한 후
pop
한다.
- Stack에 우선순위가 같거나 큰 연산자가 없을 경우에는 Stack에
push
한다.
if (cntChar == cnt_priority[0]) { opernand.push(stol(value)); value = "";
while (!operation.empty() && operation.top() == cnt_priority[0]) { long long value1 = opernand.top(); opernand.pop(); long long value2 = opernand.top(); opernand.pop(); char oper = operation.top(); operation.pop();
long long result = calValue1Value2(value1, value2, oper); opernand.push(result); }
operation.push(cntChar); }
if (cntChar == cnt_priority[1]) { opernand.push(stol(value)); value = "";
while (!operation.empty() && operation.top() != cnt_priority[2]) { long long value1 = opernand.top(); opernand.pop(); long long value2 = opernand.top(); opernand.pop(); char oper = operation.top(); operation.pop();
long long result = calValue1Value2(value1, value2, oper); opernand.push(result); }
operation.push(cntChar); }
if (cntChar == cnt_priority[2]) { opernand.push(stol(value)); value = "";
while (!operation.empty()) { long long value1 = opernand.top(); opernand.pop(); long long value2 = opernand.top(); opernand.pop(); char oper = operation.top(); operation.pop();
long long result = calValue1Value2(value1, value2, oper); opernand.push(result); }
operation.push(cntChar); }
|
Stack을 이용한 소스 코드
#include <bits/stdc++.h> using namespace std;
char operation[3] = {'*', '+', '-'}; bool check[3]; vector<char> cntCase(3); vector<vector<char>> allCase;
void makeAllCase(int depth) { if (depth == 3) { allCase.push_back(cntCase); }
for (int i = 0; i < 3; i++) { int cntOper = operation[i];
if (check[i] == false) { check[i] = true; cntCase[depth] = cntOper; makeAllCase(depth + 1); check[i] = false; } } }
long long calValue1Value2(long long value1, long long value2, char oper) { long long result = 0;
if (oper == '*') { result = value2 * value1; } else if (oper == '+') { result = value2 + value1; } else { result = value2 - value1; } return result; }
long long solveExpression(string expression) { long long maxValue = 0;
for (vector<char> cnt_priority : allCase) { stack<long long> opernand; stack<char> operation;
string value = ""; for (int i = 0; i < expression.size(); i++) { char cntChar = expression[i];
if ('0' <= cntChar && cntChar <= '9') { value += cntChar; }
if (cntChar == cnt_priority[0]) { opernand.push(stol(value)); value = "";
while (!operation.empty() && operation.top() == cnt_priority[0]) { long long value1 = opernand.top(); opernand.pop(); long long value2 = opernand.top(); opernand.pop(); char oper = operation.top(); operation.pop();
long long result = calValue1Value2(value1, value2, oper); opernand.push(result); }
operation.push(cntChar); }
if (cntChar == cnt_priority[1]) { opernand.push(stol(value)); value = "";
while (!operation.empty() && operation.top() != cnt_priority[2]) { long long value1 = opernand.top(); opernand.pop(); long long value2 = opernand.top(); opernand.pop(); char oper = operation.top(); operation.pop();
long long result = calValue1Value2(value1, value2, oper); opernand.push(result); }
operation.push(cntChar); }
if (cntChar == cnt_priority[2]) { opernand.push(stol(value)); value = "";
while (!operation.empty()) { long long value1 = opernand.top(); opernand.pop(); long long value2 = opernand.top(); opernand.pop(); char oper = operation.top(); operation.pop();
long long result = calValue1Value2(value1, value2, oper); opernand.push(result); }
operation.push(cntChar); } } opernand.push(stol(value));
while (!operation.empty()) { long long value1 = opernand.top(); opernand.pop(); long long value2 = opernand.top(); opernand.pop(); char oper = operation.top(); operation.pop();
long long result = calValue1Value2(value1, value2, oper); opernand.push(abs(result)); }
if (maxValue < opernand.top()) { maxValue = opernand.top(); } } return maxValue; }
long long solution(string expression) { long long answer = 0; makeAllCase(0); answer = solveExpression(expression); return answer; }
|
dq를 이용한 문제 해결
#include <bits/stdc++.h> using namespace std;
typedef long long ll;
char operation[3] = {'+', '-', '*'}; bool check[3]; vector<char> op(3); vector<vector<char>> operations; deque<long long> dq_opernand; deque<char> dq_operator; ll max_value = 0;
void nPr(int depth) { if (3 == depth) { vector<char> v(op); operations.push_back(op); return; }
for (int i = 0; i < 3; i++) { if (check[i] == true) continue; op[depth] = operation[i];
check[i] = true; nPr(depth + 1); check[i] = false; } }
void divideOperaion(string expression) { string s; for (int i = 0; i < expression.size(); i++) { if ('0' <= expression[i] && expression[i] <= '9') { s += expression[i]; } else { dq_opernand.push_back(stol(s)); dq_operator.push_back(expression[i]); s = ""; } } dq_opernand.push_back(stol(s)); }
long long operValue(ll a, ll b, char op) { if (op == '+') { return a + b; } else if (op == '-') { return a - b; } else { return a * b; } }
void operate(string expression) { deque<ll> temp_opernand; deque<char> temp_operator;
for (auto o : operations) { deque<ll> copy_opernand(dq_opernand); deque<char> copy_operator(dq_operator);
for (int i = 0; i < 3; i++) { char cnt_operation = o[i];
while (!copy_operator.empty()) { if (copy_operator.front() == cnt_operation) { ll value1 = copy_opernand.front(); copy_opernand.pop_front();
ll value2 = copy_opernand.front(); copy_opernand.pop_front();
char oper = copy_operator.front(); copy_operator.pop_front();
ll result = operValue(value1, value2, oper);
copy_opernand.push_front(result); } else { temp_opernand.push_back(copy_opernand.front()); temp_operator.push_back(copy_operator.front());
copy_opernand.pop_front(); copy_operator.pop_front(); } }
while (!copy_opernand.empty()) { temp_opernand.push_back(copy_opernand.front()); copy_opernand.pop_front(); }
while (!temp_operator.empty()) { copy_operator.push_back(temp_operator.front()); temp_operator.pop_front(); }
while (!temp_opernand.empty()) { copy_opernand.push_back(temp_opernand.front()); temp_opernand.pop_front(); } } max_value = max(max_value, abs(copy_opernand.front())); } }
long long solution(string expression) { long long answer; nPr(0); divideOperaion(expression); operate(expression); answer = max_value; return answer; }
|