https://school.programmers.co.kr/learn/courses/30/lessons/67257
해당 문제는 단순 구현 문제로, 문자열 처리가 중점인 문제이다.
1) 입력받은 expression
문자열을 각 숫자와 연산자로 따로 나누어 저장한다.
split()
함수 : 인수로 전달된 문자열을 숫자와 연산자로 나누어 같은 벡터에 순서대로 저장한다.result
벡터에 집어넣고, 기존 문자열을 연산자 뒤의 문자열로 교체한다.result
벡터에 집어넣고 result
를 반환한다.nums
와 op
를 선언하고, split()
함수에서 반환된 벡터를 확인하여 숫자 문자열은 nums
에, 연산자는 op
에 삽입한다.2) 2차원 벡터 orders
를 선언해 3개의 연산자로 만들 수 있는 우선순위 6개를 저장한다.
3) orders
에 저장된 각각의 연산자 우선순위에 따라 주어진 문자열을 계산한다.
nums
와 op
를 numsCopy
, opCopy
에 복사해 저장한다.orders
에 저장된 연산자들을 순서대로 적용하여 아래 과정을 반복한다.opCopy
에 저장된 각 연산자를 차례대로 확인한다.orders
의 현재 순서 연산자가 아니라면 다음 연산자로 넘어간다.opCopy
의 끝 인덱스까지 확인할 때까지 아래 과정을 반복한다.numsCopy
에 저장된 해당 연산자의 앞과 뒤에 있는 숫자들을 해당 연산자로 계산해numsCopy
에 앞에 있는 숫자의 위치에 저장한다.opCopy
의 해당 연산자와, numsCopy
의 뒤에 있는 숫자를 삭제한다.opCopy
의 맨 앞으로 돌아간다.opCopy
의 끝까지 확인했다면 orders
의 다음 순서 연산자로 넘어간다.numsCopy
에 계산 완료된 숫자 하나만이 남는다. 이 숫자를 result
벡터에 삽입한다.4) 6개의 우선순위를 각각 적용하여 계산된 값들이 최종적으로 result
에 저장되고, 이 값들의 절대값들을 비교하여 가장 큰 값을 출력한다.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <list>
using namespace std;
// 문자열을 각 연산자를 기준으로 나누어 숫자와 연산자로 저장
vector<string> split(string str)
{
char dlim1 = '*', dlim2 = '+', dlim3 = '-';
vector<string> result;
int a, b, c;
while (true)
{
a = find(str.begin(), str.end(), dlim1) - str.begin();
b = find(str.begin(), str.end(), dlim2) - str.begin();
c = find(str.begin(), str.end(), dlim3) - str.begin();
if (a == str.size() && b == str.size() && c == str.size())
{
result.push_back(str);
return result;
}
else
{
int dlim = min({ a, b, c });
result.push_back(str.substr(0, dlim));
result.push_back(str.substr(dlim, 1));
str = str.substr(dlim + 1, str.size() - dlim);
}
}
}
long long solution(string expression)
{
// 연산자는 op, 숫자는 nums에 저장
vector<string> v = split(expression);
list<string> nums, op;
for (int i = 0; i < v.size(); i++)
{
if (v[i] == "*" || v[i] == "+" || v[i] == "-")
op.push_back(v[i]);
else
nums.push_back(v[i]);
}
vector<vector<string>> orders;
orders.push_back({ "*", "+", "-" });
orders.push_back({ "*", "-", "+" });
orders.push_back({ "+", "*", "-" });
orders.push_back({ "+", "-", "*" });
orders.push_back({ "-", "+", "*" });
orders.push_back({ "-", "*", "+" });
vector<long long> result;
for (int i = 0; i < orders.size(); i++)
{
list<string> numsCopy = nums, opCopy = op;
for (int k = 0; k < 3; k++)
{
int j = 0;
while(true)
{
if (j >= opCopy.size())
break;
auto it = opCopy.begin(); // 연산자 이터레이터
advance(it, j);
if (*it != orders[i][k])
{
j++;
continue;
}
auto prevNumsIt = numsCopy.begin(); // 연산자 이전 글자 이터레이터
auto postNumsIt = numsCopy.begin(); // 연산자 다음 글자 이터레이터
advance(prevNumsIt, j);
advance(postNumsIt, j + 1);
if (*it == "*")
*prevNumsIt = to_string(stoll(*prevNumsIt) * stoll(*postNumsIt));
else if (*it == "+")
*prevNumsIt = to_string(stoll(*prevNumsIt) + stoll(*postNumsIt));
else
*prevNumsIt = to_string(stoll(*prevNumsIt) - stoll(*postNumsIt));
opCopy.erase(it);
numsCopy.erase(postNumsIt);
j = 0;
}
}
result.push_back(stoll(*numsCopy.begin()));
}
long long maxValue = 0;
for (int i = 0; i < result.size(); i++)
{
long long cur = llabs(result[i]);
if (cur > maxValue)
maxValue = cur;
}
return maxValue;
}