Koala - 11기/코딩테스트 준비 스터디

[프로그래머스/Java] 수식 최대화 lv2

알 수 없는 사용자 2023. 7. 16. 12:44

https://school.programmers.co.kr/learn/courses/30/lessons/67257

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제의 설명이 매우 길어 링크로 대신 첨부합니다.

해결방법: 주어진 입력 값이 적을 때에는 재귀보다 직접 연산을 이용

제한사항

  • expression은 길이가 3 이상 100 이하인 문자열입니다.
  • expression은 공백문자, 괄호문자 없이 오로지 숫자와 3가지의 연산자(+, *) 만으로 이루어진 올바른 중위표기법(연산의 두 대상 사이에 연산기호를 사용하는 방식)으로 표현된 연산식입니다. 잘못된 연산식 은 입력으로 주어지지 않습니다.

연산 우선순위는 6가지 밖에 없으므로 직접 연산을 택했습니다.

import java.util.*;
class Solution {
   
    // +, -, * 총 3가지 연산자이므로 가능한 경우의 수는 6가지 밖에 없고
    // 따라서 재귀보다 나열이 더 빠를 수 있음
    private static final String[][] precedences={
         "+-*".split(""), //["+","-","*"]와 같은 문자열 배열이 생성
         "+*-".split(""),
         "-+*".split(""),
         "-*+".split(""),
         "*+-".split(""),
         "*-+".split(""),
    };
    private long calculate(long lhs, long rhs, String op){
        return switch (op){
                case "+" ->lhs + rhs;
                case "-" ->lhs - rhs;
                case "*" ->lhs * rhs;
                default -> 0;
        }; //식이 주어지면 계산하는 함수
    }
  
    
    private long calculate(List<String> tokens, String[] precedence) { 
        for(String op: precedence){
            for(int i=0;i<tokens.size();i++){
                if(tokens.get(i).equals(op)){
                    long lhs=Long.parseLong(tokens.get(i-1));
                    long rhs=Long.parseLong(tokens.get(i+1));
                    long result= calculate(lhs,rhs,op);
                  
                    tokens.remove(i-1); //사용한 연산자 제거
                    tokens.remove(i-1);
                    tokens.remove(i-1);
                    tokens.add(i-1,String.valueOf(result));
                    i-=2;
                }
            }
        }
        return Long.parseLong(tokens.get(0));
    }
    
    public long solution(String expression) {
         //문자열의 splitO 메서드를 사용하여 연산자를 기준으로 문자열을 분리한다면 
         // 연산자와 숫자는 나눌 수 있지만 분리 기준인 연산자는 잃게 됨
         // 따라서 이 문제에서는 StringTokenizer 클래스로 다음과 같이 문자열을 분리
    
    StringTokenizer tokenizer= new StringTokenizer(expression,"+-*",true);
    List<String> tokens= new ArrayList<>();
    while(tokenizer.hasMoreTokens()){
        tokens.add(tokenizer.nextToken());
    }
        long max=0;
        for(String[] precedence: precedences){
            long value= Math.abs(calculate(new ArrayList<>(tokens),precedence));
            if(value >max){
                max=value;
            }
        }
        return max;
    }
}