[programmers] 주차 요금 계산(JAVA)

mark1106·2024년 3월 11일
0

프로그래머스

목록 보기
5/6
post-thumbnail

문제

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

풀이

다음과 같은 요금표와 입/출차 기록이 있을 때 차량이 주차한 시간을 계산하고 요금표에 맞게 주차 비용을 계산하는 문제이다.

먼저 입차-출차한 차량의 시간을 계산한다.
입차만 하고 출차 기록은 없는 차량은 출차 기록을 23:59분으로 계산한다.

이 조건으로 단순하게 바로 떠오르는 풀이는 입차한 차량을 HashMap<차량번호, 입차 시간>에 넣고 출차된 차량을 HashMap에서 꺼내 (출차 시간 - 입차 시간)을 배열에 저장하는 것이다.

그 코드는 다음과 같다.

			if(status.equals("IN")){ // 입차 차량을 map에 넣기
                parkingCars.put(carNumber, time);
            }
            else{ // 출차 차량일때 시간 계산 후 totalTime에 더하기
                int duringTime = time - parkingCars.get(carNumber);
                parkingCars.remove(carNumber);
                //이미 입차-출차로 기록된 차량이 추후에 입차-출차 되는 경우도 있으므로 확인
                totalTime.put(carNumber, totalTime.getOrDefault(carNumber, 0) + duringTime);
           	}

위에 코드에서 주의해야 할 점은 입차-출차가 여러 번 될 수 있다는 것이다. 따라서 입차-출차 기록이 기존 totalTime에 있으면 더하고, 처음이라면 주차 시간을 totalTime에 넣어줘야 한다.

입차-출차한 차량의 주차 시간을 모두 계산하면 parkingCars라는 HashMap에는 출차되지 않고 입차만 된 차량이 남아있을 것이다. 문제 조건에서 입차만 하고 출차되지 않은 차량은 23:59분에 일괄로 출차 처리해야 한다.

		for(Integer carNumber : parkingCars.keySet()){
            int duringTime = 60 * 23 + 59 - parkingCars.get(carNumber);
            totalTime.put(carNumber, totalTime.getOrDefault(carNumber, 0) + duringTime);
        }

그 후 정산 조건에 따라 주차 요금을 정산해준 후 int배열로 반환해주면 된다.

		for(Integer carNumber : totalTime.keySet()){
            int charge = fees[1];
            if(totalTime.get(carNumber) > fees[0]){
                charge += Math.ceil((double)(totalTime.get(carNumber) - fees[0]) / fees[2]) * fees[3];
            }
            result.add(charge);
        }
        
        return result.stream()
            .mapToInt(Integer::intValue)
            .toArray();

깨달은 점

조건에 따라 구현만 하면 되는 문제이지만 문제를 제대로 읽지 않아 시간이 많이 걸렸던 문제이다.

요금을 일괄로 정산 이라는 조건을 보지 못하고 입차-출차한 경우 바로 정산을 하여 틀렸음에도 불구하고 찾는데 오래 걸렸다.

또한 TreeMap 자료 구조를 처음 사용하였다.
HashMap이랑 비슷하지만 TreeMap은 Key 값을 오름차순으로 정렬하여 저장한다.

따라서 문제 조건에서 차량 번호 순으로 반환하라는 조건을 TreeMap을 사용하여 편리하게 구현할 수 있었다.

코드

import java.util.*;
import java.io.*;

class Solution {
    public int[] solution(int[] fees, String[] records) {
        HashMap<Integer, Integer> parkingCars = new HashMap<>();
        TreeMap<Integer, Integer> totalTime = new TreeMap<>();
        List<Integer> result = new ArrayList<>();
        
        for(int i = 0; i < records.length;i++){
            String[] record = records[i].split(" ");
            int time = getTime(record[0]);
            int carNumber = Integer.parseInt(record[1]);
            String status = record[2];
            
            if(status.equals("IN")){
                parkingCars.put(carNumber, time);
            }
            else{ // 출차 차량일때
                int duringTime = time - parkingCars.get(carNumber);
                parkingCars.remove(carNumber);
                totalTime.put(carNumber, totalTime.getOrDefault(carNumber, 0) + duringTime);
            }
        }
        
        for(Integer carNumber : parkingCars.keySet()){
            int duringTime = 60 * 23 + 59 - parkingCars.get(carNumber);
            totalTime.put(carNumber, totalTime.getOrDefault(carNumber, 0) + duringTime);
        }
        
        for(Integer carNumber : totalTime.keySet()){
            int charge = fees[1];
            if(totalTime.get(carNumber) > fees[0]){
                charge += Math.ceil((double)(totalTime.get(carNumber) - fees[0]) / fees[2]) * fees[3];
            }
            result.add(charge);
        }
        
        return result.stream()
            .mapToInt(Integer::intValue)
            .toArray();
        
    }

    int getTime(String record){
        String[] times = record.split(":");
        return Integer.parseInt(times[0]) * 60 + Integer.parseInt(times[1]);
    }
    
}
profile
뒤돌아보면 남는 것은 사진, 그리고 기록 뿐

0개의 댓글