해당 문제 링크
https://school.programmers.co.kr/learn/courses/30/lessons/67257
하나의 문자열로 제공해준 수식을 숫자 부분과 연산자를 분리해서 가장 큰 결과값을 나오게하면 되는 문제이다. 필요한 기능들을 정리해본다면 이렇게 나온다.
public List<Long> findNumbers(String expression){
List<Long> numbers = new ArrayList<>();
String temp = "";
for(int i=0; i<expression.length(); i++){
char findChar = expression.charAt(i);
if(findChar == '+' || findChar == '-' || findChar == '*'){
Long number = Long.parseLong(temp);
numbers.add(number);
temp = "";
continue;
}
temp += findChar;
}
//마지막 남은 숫자
Long number = Long.parseLong(temp);
numbers.add(number);
return numbers;
}
다른 사람의 풀이를 보면 정규식으로 문자열에서 바로 split() 해서 분리하는 소스도 보았다.
public List<String> findOperators(String expression){
List<String> operators = new ArrayList<>();
for(int i=0; i<expression.length(); i++){
char findChar = expression.charAt(i);
if (findChar == '+'){
operators.add("+");
}else if (findChar == '-'){
operators.add("-");
}else if (findChar == '*'){
operators.add("*");
}
}
return operators;
}
해당 기능도 문자열에서 숫자를 replaceAll() 해서 지운뒤에 split()한 소스도 보았는데 깔끔하니 보기 좋았다.
연산자 우선순위는 dfs를 통해서 구하려고 하다가 최대 6가지 종류밖에 나오지않아서 그냥 수동으로 제작했다.
String[][] calculateOrders = {
{"+", "-", "*"},
{"+", "*", "-"},
{"-", "+", "*"},
{"-", "*", "+"},
{"*", "-", "+"},
{"*", "+", "-"}
};
for(int i=0; i<calculateOrders.length; i++){
long result = 0;
result = calculate(calculateOrders[i], numbers, operators);
answer = Math.max(answer, Math.abs(result));
}
1+2-3*4를 예로 들면 numbers = {1,2,3,4}, operators = {+, -, *}가 들어있고
연산우선순위는 "+ > - > *" 일 때 작업순서를 정리하면 이렇게 된다.
public Long calculate(String[] calculateOrder, List<Long> numbers, List<String> operators){
//복사
List<Long> cpNumbers = new ArrayList<>(numbers);
List<String> cpOperators = new ArrayList<>(operators);
for(String operator : calculateOrder){
while(cpOperators.contains(operator)){
// 1번
int findOperatorIndex = cpOperators.indexOf(operator);
// 2번
long a = cpNumbers.get(findOperatorIndex);
long b = cpNumbers.remove(findOperatorIndex + 1);
// 3번, 5번
if(operator.equals("+")){
cpNumbers.set(findOperatorIndex, a + b);
}else if(operator.equals("-")){
cpNumbers.set(findOperatorIndex, a - b);
}else{
cpNumbers.set(findOperatorIndex, a * b);
}
// 4번
cpOperators.remove(findOperatorIndex);
}
}
return cpNumbers.get(0);
}
import java.util.*;
class Solution {
public long solution(String expression) {
long answer = 0;
List<Long> numbers = findNumbers(expression);
List<String> operators = findOperators(expression);
String[][] calculateOrders = {
{"+", "-", "*"},
{"+", "*", "-"},
{"-", "+", "*"},
{"-", "*", "+"},
{"*", "-", "+"},
{"*", "+", "-"}
};
for(int i=0; i < calculateOrders.length; i++){
long result = 0;
result = calculate(calculateOrders[i], numbers, operators);
answer = Math.max(answer, Math.abs(result));
}
return answer;
}
public Long calculate(String[] calculateOrder, List<Long> numbers, List<String> operators){
List<Long> cpNumbers = new ArrayList<>(numbers);
List<String> cpOperators = new ArrayList<>(operators);
for(String operator : calculateOrder){
while(cpOperators.contains(operator)){
int findOperatorIndex = cpOperators.indexOf(operator);
cpOperators.remove(findOperatorIndex);
long a = cpNumbers.get(findOperatorIndex);
long b = cpNumbers.remove(findOperatorIndex + 1);
if(operator.equals("+")){
cpNumbers.set(findOperatorIndex, a + b);
}else if(operator.equals("-")){
cpNumbers.set(findOperatorIndex, a - b);
}else{
cpNumbers.set(findOperatorIndex, a * b);
}
}
}
return cpNumbers.get(0);
}
public List<Long> findNumbers(String expression){
List<Long> numbers = new ArrayList<>();
String temp = "";
for(int i=0; i<expression.length(); i++){
char findChar = expression.charAt(i);
if(findChar == '+' || findChar == '-' || findChar == '*'){
Long number = Long.parseLong(temp);
numbers.add(number);
temp = "";
continue;
}
temp += findChar;
}
Long number = Long.parseLong(temp);
numbers.add(number);
return numbers;
}
public List<String> findOperators(String expression){
List<String> operators = new ArrayList<>();
for(int i=0; i<expression.length(); i++){
char findChar = expression.charAt(i);
if (findChar == '+'){
operators.add("+");
}else if (findChar == '-'){
operators.add("-");
}else if (findChar == '*'){
operators.add("*");
}
}
return operators;
}
}
String[] numbers = expression.split("[*,\\-,+]");
char[] operators = expression.replaceAll("[0-9]", "")
.trim()
.toCharArray();
이렇게 숫자부분과 연산자 부분을 분리하는 방법을 봤는데 간단하니 보기도 좋았다. 이후 연산자의 우선순위를 DFS로 찾는 사람도 있었다.