본문 바로가기
코딩테스트/programming_JAVA

[Java] 프로그래머스_67257 : 수식 최대화

by prometedor 2023. 11. 20.

완전 탐색

수식 최대화 - Level 2

 

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

 

프로그래머스

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

programmers.co.kr

 

 

 

풀이1

import java.util.*;

class Solution {
    
    private static final String[][] preferences = {
        "+-*".split(""),
        "+*-".split(""),
        "-+*".split(""),
        "-*+".split(""),
        "*+-".split(""),
        "*-+".split(""),
    };
    
    private long calculate(long left, long right, String op) {
        // 두 피연산자와 연산자를 입력받아 연산 결과를 반환하는 메서드
        return switch (op) {
            case "+" -> left + right;
            case "-" -> left - right;
            case "*" -> left * right;
            default -> 0;
        };
    }
    
    private long calculate(List<String> tokens, String[] preference) { 
        // 연산자 우선 순위를 이용하여 계산하는 메서드
        for (String op : preference) {
            for (int i = 0; i < tokens.size(); i++) {
                if (tokens.get(i).equals(op)) {
                    long left = Long.parseLong(tokens.get(i - 1));
                    long right = Long.parseLong(tokens.get(i + 1));
                    long ret = calculate(left, right, op);
                    tokens.remove(i - 1);
                    tokens.remove(i - 1);
                    tokens.remove(i - 1);
                    tokens.add(i - 1, String.valueOf(ret));
                    i -= 2;
                }
            }
        }
        return Long.parseLong(tokens.get(0));
    }
    
    public long solution(String expression) {
        
        StringTokenizer tokenizer = new StringTokenizer(expression, "+-*", true);
        List<String> tokens = new ArrayList<>();
        while (tokenizer.hasMoreTokens()) {
            tokens.add(tokenizer.nextToken());
        }
        
        long max = 0;
        for (String[] preference : preferences) {
	    // calculate() 메서드는 내부에서 전달된 tokens의 원소를 수정한다.
    	    // 수식은 여러 연선자 우선순위에 대해 반복적으로 적용해야 하므로 리스트를 복사해서 넘겨준다.
            long value = Math.abs(calculate(new ArrayList<>(tokens), preference));
            if (value > max) {
                max = value;
            }
        }
        return max;
    }
}

 

 

switch 표현식

result = switch (변수) {
    case 값1 -> 처리;
    case 값2 -> 처리;
    // ...
    default -> 기본 처리;
}

 

ㄴ switch 표현식(또는 switch 식)은 Java 12부터 도입되었다.

ㄴ switch 표현식은 기존의 switch 문을 보완하여 식(expression)으로 사용할 수 있게 해주는 기능이다.

ㄴ 여기서 -> 는 "이 경우에는 다음의 값을 반환한다"라는 의미이다.

ㄴ 풀이 코드에서는 op 변수에 따라 덧셈, 뺄셈, 곱셈을 수행하고 해당 결과를 반환하고 있습니다.

 

switch (변수) {
    case 값1:
        // 처리
        break;
    case 값2:
        // 처리
        break;
    // ...
    default:
        // 기본 처리
}

 

ㄴ 기존에 알고있던 switch 문

 

 

StringTokenizer 

StringTokenizer은 주어진 구분자(delimiter)를 사용하여 문자열을 토큰(token)으로 분리하는 Java의 클래스이다.

StringTokenizer tokenizer = new StringTokenizer(expression, "+-*", true);

 

ㄴ expression : 분리할 대상이 되는 문자열이다.
ㄴ "+-*" : 구분자(delimiter)로 사용될 문자들을 나열한 문자열이다. 여기서는 +, -, *를 구분자로 사용한다.
ㄴ true : 구분자도 토큰으로 포함할 것인지를 나타내는 boolean 값이다.
=> 이 코드는 주어진 expression 문자열을 +, -, * 기호를 구분자로 사용하여 토큰으로 나누는데, true를 설정했으므로 구분자도 토큰으로 간주한다.

예를 들어, "50*6-3*2"라는 문자열이 주어졌을 때, 이는 다음과 같이 토큰으로 분리될 수 있다.
=>
"50"
"*"
"6"
"-"
"3"
"*"

"2"

 

 

hasMoreTokens(), nextToken()

StringTokenizer tokenizer = new StringTokenizer(expression, "+-*", true);
List<String> tokens = new ArrayList<>();
while (tokenizer.hasMoreTokens()) {
	tokens.add(tokenizer.nextToken());
}

 

ㄴ StringTokenizer를 사용하여 문자열을 토큰으로 분리하고, 그 결과를 List<String>에 담는 부분이다.

ㄴ List<String> tokens = new ArrayList<>(); : 문자열 토큰을 저장할 ArrayList를 생성한다.
ㄴ while (tokenizer.hasMoreTokens()) { : StringTokenizer에 아직 처리하지 않은 토큰이 남아있는지 확인하는 조건문이다.

     즉, 아직 토큰을 더 가져올 수 있는 동안에 반복합니다.
ㄴ tokens.add(tokenizer.nextToken()); : StringTokenizer에서 다음 토큰을 가져와서 tokens 리스트에 추가한다.

 

=> 이러한 과정을 통해 StringTokenizer를 사용하여 문자열을 토큰으로 나누고, 각 토큰을 List<String>에 저장한다.

 

 

카카오 문제는 참 풀기 복잡한 것 같다......^-^