알고리즘 문제 풀이

[Swift] 프로그래머스 LV2. 수식 최대화

lgvv 2022. 4. 16. 17:12

프로그래머스 LV2. 수식 최대화

 

✅ 구현만 하면 문제였는데, 은근히 오래걸렸다.

내가 구현에서 생각보다 오래걸리는데, 문제를 생각하고 설계는 빨리 마치는데, 근데 자꾸 어떤 문제가 발생한다..

예외처리가 부족하기도 하지만, 그보다도 코드상에서 remove 같은 작업에서 발생하는 실수가 너무 많다.

 

 

✅ 코드

알고리즘 접근법에 대해서 처음에는 계산기 알고리즘을 사용하려고 했다.

중위 후위 등 구글에 치면 다양한 알고리즘이 나온다!! 

하지만 난, 꼭 그런걸 정량적으로 알고 있어야 문제를 푸는건 불만이었기에 다른 로직으로 내 방식대로 풀어보았다.

priority를 6번 반복하는 이유는 어차피 연산자 3개로 우선순위를 매기는 경우의 수가 6가지 밖에 되지 않는다.

 

두번째는 while문인데, 연산자를 찾아서 그 연산자의 앞뒤로 해당하는 연산을 처리하고

결과값을 배열에 넣어주고 이미 계산한 숫자와 연산자를 배열에서 모두 삭제해줌으로써 새로운 배열을 세팅한다.

그렇게 우선순위에 따라서 처리하고나서 답을 구하면 끝ㅋ !

 

마지막으로 출력부에서 알아두면 좋은 부분인데, max안에 abs를 같이 넣었더니 시간 초과가 나서 이는 밖으로 빼서 계산했다.

 

 

//
//  67257.swift
//  Algorithm
//
//  Created by Hamlit Jason on 2022/04/16.
//
// https://programmers.co.kr/learn/courses/30/lessons/67257
import Foundation

struct p67257 {
    static func run() {
        print(p67257.solution("100-200*300-500+20")) // 60420
        // * > + > - 순서 : 100 - 60000 - 520  = 60420
        // array : 100, -, 60000, -, 520
//                print(p67257.solution("50*6-3*2")) // 300
        // - > * 순서: 50, *, 3, * 2
        
        
    }
    
    static func solution(_ expression:String) -> Int64 {
        
        let numbers = expression.split { $0 == "*" || $0 == "+" || $0 == "-" }.map { String($0) }
        let operators = expression.split { $0.isNumber }.map { String($0) }
        
        
        var list = [String]()
        for i in 0..<operators.count {
            list.append(numbers[i])
            list.append(operators[i])
        }
        list.append(numbers.last!)
//        print("list \(list)")
        
        // 오퍼레이터의 우선순위를 설정합니다.
        let priority = [
            ("*","-","+"),
            ("*","+","-"),
            ("+","*","-"),
            ("+","-","*"),
            ("-","+","*"),
            ("-","*","+")
        ]
        
        var sumArray = [Int](repeating: 0, count: 6)
        var copyList = list
        
        for i in 0..<priority.count {
            copyList = list
            let first = priority[i].0
            let second = priority[i].1
            let third = priority[i].2
            
            while copyList.contains(first) {
                let index = copyList.firstIndex(of: first)!
                
                sumArray[i] = caculate(a: Int(copyList[index-1])!, b: Int(copyList[index+1])!, oper: first)
                
                copyList.insert(String(sumArray[i]), at: index+2)
                
                copyList.remove(at: index-1)
                copyList.remove(at: index-1)
                copyList.remove(at: index-1)
            }
            
            while copyList.contains(second) {
                let index = copyList.firstIndex(of: second)!
                sumArray[i] = caculate(a: Int(copyList[index-1])!, b: Int(copyList[index+1])!, oper: second)
                copyList.insert(String(sumArray[i]), at: index+2)
                
                copyList.remove(at: index-1)
                copyList.remove(at: index-1)
                copyList.remove(at: index-1)
                
            }
            
            while copyList.contains(third) {
                let index = copyList.firstIndex(of: third)!
                sumArray[i] = caculate(a: Int(copyList[index-1])!, b: Int(copyList[index+1])!, oper: third)
                copyList.insert(String(sumArray[i]), at: index+2)
               
                copyList.remove(at: index-1)
                copyList.remove(at: index-1)
                copyList.remove(at: index-1)
            }
            
        }
//        print(sumArray)
        var maxValue = 0
        sumArray.forEach { value in
            let value = abs(value)
            maxValue = max(value, maxValue)
        }
        
        return Int64(maxValue)
    }
    
    static func caculate(a: Int, b: Int, oper: String) -> Int {
        switch oper {
        case "*": return a * b
        case "-": return a - b
        case "+": return a + b
        default: return -1
        }
    }
}

 

성능이 매우 좋다!