본문 바로가기
JAVA/프로그래머스

[Lv.2] 프로그래머스 - 주차 요금 계산 : Java

by ♡˖GYURI˖♡ 2024. 5. 30.
 

프로그래머스

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

programmers.co.kr

 

 

 

 

이해하기

fees 배열에는 다음과 같은 정보가 들어있다.

  • 기본 시간
  • 기본 요금
  • 단위 시간
  • 단위 요금

records에는 각 차의 입출 시간, 차 번호, 입출 여부가 들어있다.

 

각 차가 들어온 시간과 나간 시간을 계산하고, 누적된 시간에 대한 요금을 계산한다.

단, 출차 처리가 되지 않았을 경우 23:59에 출차한 것으로 계산한다.

 

내용이 너무 길어서 복잡했지만 정리하면 생각보다 간단했다.

다만 구현이 어려울 뿐 ㅎㅎ...

 

참고한 블로그⬇️

 

[Java/자바] 프로그래머스 Lv2 - 주차 요금 계산 (HashMap, TreeMap)

문제 설명 주차장의 요금표와 차량이 들어오고(입차) 나간(출차) 기록이 주어졌을 때, 차량별로 주차 요금을 계산하려고 합니다. 아래는 하나의 예시를 나타냅니다. 요금표 기본 시간(분) 기본

hstory0208.tistory.com

 

Map을 정렬할 수 있나? 했지만 TreeMap을 사용하면 된다네...^^

자료구조를 좀 더 공부해야 할 것 같다.

 

 

문제풀이

import java.util.*;

class Solution {
    public int[] solution(int[] fees, String[] records) {
        Map<String, Integer> parking = new HashMap<>();
        Map<String, Integer> totalFee = new TreeMap<>();
        
        for (String record : records) {
            String[] temp = record.split(" ");
            int time = getTime(temp[0]);
            String car = temp[1];
            String inOut = temp[2];
            
            if (inOut.equals("IN")) {
                parking.put(car, time);
            } else {
                if (!totalFee.containsKey(car)) {
                    totalFee.put(car, time - parking.get(car));
                } else {
                    totalFee.put(car, totalFee.get(car) + time - parking.get(car));
                }
                parking.remove(car);
            }
        }
        
        if (!parking.isEmpty()) {
            for (String car : parking.keySet()) {
                Integer fee = totalFee.get(car);
                fee = (fee == null) ? 0 : fee;
                totalFee.put(car, fee + (23 * 60 + 59) - parking.get(car));
            }
        }
        
        List<Integer> list = new ArrayList<>();
        for (Integer t : totalFee.values()) {
            int baseTime = fees[0];
            int baseFee = fees[1];
            int partTime = fees[2];
            int partFee = fees[3];
            
            if (t <= baseTime) {
                list.add(baseFee);
            } else {
                list.add((int) (baseFee + Math.ceil((double)(t - baseTime) / partTime) * partFee));
            }
        }
        
        return list.stream().mapToInt(Integer::intValue).toArray();
    }
    
    public int getTime(String s) {
        String[] temp = s.split(":");
        return Integer.parseInt(temp[0]) * 60 + Integer.parseInt(temp[1]);
    }
}

 

        Map<String, Integer> parking = new HashMap<>();
        Map<String, Integer> totalFee = new TreeMap<>();

 

map에는 차량의 입차 정보를 담을 것이고, totalFee는 차량 번호가 작은 자동차부터 정렬하여 저장할 것이다.

 

        for (String record : records) {
            String[] temp = record.split(" ");
            int time = getTime(temp[0]);
            String car = temp[1];
            String inOut = temp[2];

 

record를 하나씩 순회하며 각각의 시간, 차량 번호, 입출 여부를 변수에 저장한다.

 

    public int getTime(String s) {
        String[] temp = s.split(":");
        return Integer.parseInt(temp[0]) * 60 + Integer.parseInt(temp[1]);
    }

 

위에서 사용된 getTime() 함수는 시간 * 60 + 분 = 총 시간(분) 을 구하여 반환하는 함수이다.

 

            if (inOut.equals("IN")) {
                parking.put(car, time);
            } else {
                if (!totalFee.containsKey(car)) {
                    totalFee.put(car, time - parking.get(car));
                } else {
                    totalFee.put(car, totalFee.get(car) + time - parking.get(car));
                }
                parking.remove(car);
            }

 

만약 IN인 차라면 parking이라는 HashMap에 차 번호와 (들어온) 시간을 저장한다.

아니라면 (OUT이라면) totalFee라는 TreeMap에 저장되어 있는지 여부를 확인한다.

아직 totalFee에 저장되어 있지 않은 차 번호라면 첫 출차라는 것이니 time (출차 시간) - parking.get(car) (아까 저장한 입차 시간) 을 계산해서 저장해준다.

totalFee에 이미 저장되어 있다면 출차를 한 번 했다는 것이니 totalFee.get(car) (이전에 저장한 출차 - 입차 시간) + (현재 출차 - 입차 시간) 을 저장한다.

totalFee에 저장한 후에는 parking에서 삭제시킨다.

 

        if (!parking.isEmpty()) {
            for (String car : parking.keySet()) {
                Integer fee = totalFee.get(car);
                fee = (fee == null) ? 0 : fee;
                totalFee.put(car, fee + (23 * 60 + 59) - parking.get(car));
            }
        }

 

만약 parking이 비어있지 않다면 입차 후 출차하지 않은 차들이 있다는 것이니 23:59에 출차한 것으로 계산하여 totalFee에 저장한다.

 

        List<Integer> list = new ArrayList<>();
        for (Integer t : totalFee.values()) {
            int baseTime = fees[0];
            int baseFee = fees[1];
            int partTime = fees[2];
            int partFee = fees[3];
            
            if (t <= baseTime) {
                list.add(baseFee);
            } else {
                list.add((int) (baseFee + Math.ceil((double)(t - baseTime) / partTime) * partFee));
            }
        }

 

기본 시간을 넘지 않았다면 기본 요금만, 넘었다면 기본 요금 + (넘은 시간 / 단위 시간 ) * 단위 요금을 계산하여 list에 저장한다.

 

        return list.stream().mapToInt(Integer::intValue).toArray();

 

int 배열로 변환해서 반환해주기~