출처: https://bumcrush.tistory.com/182 [맑음때때로 겨울]
반응형

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

 

프로그래머스

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

programmers.co.kr

package Programmers;

import java.sql.Time;
import java.util.*;

public class 주차요금계산 {
    public static void main(String[] args){
        주차요금계산 T = new 주차요금계산();
        int[] fees = {180, 5000, 10, 600}; //기본시간, 기본요금, 단위시간, 단위요금
        String[] records = {"05:34 5961 IN", "06:34 5961 OUT", "07:34 5961 IN",
                "08:34 5961 OUT", "09:34 5961 IN", "10:34 5961 OUT", "11:34 5961 IN", "12:34 5961 OUT"};

        T.solution(fees, records);
    }
    public int[] solution(int[] fees, String[] records) {
        int[] answer = {};
        Map<String, Integer> myRecords = new HashMap<>();
        Map<String, Integer> in = new HashMap<>();

        //차량별 시간을 기록하느 myRecords Map을 만든다.
        for (String s: records) {
            String[] splitRecords = s.split(" ");
            int m = TimeToMin(splitRecords[0]);
            String carNum = splitRecords[1];
            if(splitRecords[2].equals("IN")){
                in.put(carNum, m);
            }else{
                int useM = m - in.get(carNum);
                myRecords.put(carNum, myRecords.getOrDefault(carNum, 0) + useM);
                in.remove(carNum); //출차 in에서 삭제해준다.
            }
        }
        //출차하지 않은차 처리
        for (String carNum : in.keySet()) {
            int limitM = TimeToMin("23:59");
            int useM = limitM - in.get(carNum);
            myRecords.put(carNum, myRecords.getOrDefault(carNum, 0) + useM);
            //in.remove(carNum); //출차 in에서 삭제해준다.
        }


        List<String> keySet = new ArrayList<>(myRecords.keySet());
        Collections.sort(keySet); //자동차넘버 순대로 정렬
        List<Integer> feeList = new ArrayList<>();

        for (String carNum: keySet) {
            //기본시간보다 많이 주차했을경우
            if(myRecords.get(carNum) > fees[0]){
                double overT =  (double)(myRecords.get(carNum) - fees[0]) / fees[2]; //사용시간 올림처리
                int fee = (int) (fees[1] + Math.ceil(overT) * fees[3]);
                feeList.add(fee);
            }else{
                feeList.add(fees[1]);
            }
        }
        answer = feeList.stream()
                .mapToInt(Integer::intValue)
                .toArray();
        return answer;
    }

    public int TimeToMin(String time){
        String[] splitT = time.split(":");
        String hourS = splitT[0];
        String minS = splitT[1];
        int convertMin = Integer.parseInt(hourS)*60 + Integer.parseInt(minS);
        return convertMin;
    }
}

1. 풀이 

 - records 배열을 돌면서 myRecord Hashmap을 완성시킨다. 

  (myRecord 은 ( 차량번호, 주차장이용시간) 으로 이뤄져있음) 

 - myRecord 를 만들기 위해서 in Hashmap 을사용한다. 

    "IN" 일경우 in Map에 추가한다. (구현해놓은 TimeToMin 메서드 활용해서 시간을 분으로 치환한다)

    "OUT"일경우 in Map에 추가되어있는 시간을 찾아서 OUT 일때 출차시간 - IN 일때 입차시간 해서 그 둘의 차를 구한다. 

    myRecord에 차이만큼 ( 차넘버, 시간 ) 을 추가해준다. 

    (이미 myRecord에 있는데 또 들어올수도 있으니 있을경우에는 값을 더해준다.)

 - "IN" 만하고 "OUT" 을 하지 않는 경우가 있음 이럴경우에는 in Map에 남아있는 경우들이니까 얘내들 빼서 "23:59" 시간과 차이를 구      해준다. 

 - myRecord 에 들어있는 Key의 CarNumber를 오름차순으로 정렬해준다. (정답넣을때 차넘버 순으로 요금 정렬해주기 위해서) 

 - 이제 요금을 계산하는데 myRecord 의 Key를 돌면서 차례로 구해준다.

    기본요금보다 클때만 따로 계산을 해주는데 overT 를 double로 먼저 구하고 올림처리해준다. (154분 주차했을때 10분단위시간이면 15.4 인데 16으로 계산해야한다. int 로 계산 때리면 15가 나옴) 

 - 최종적으로 fee를 구해주면 된다. 

 

※ 처음 답안 제출했을때 1, 3 ~ 12 번까지 런타임 오류가 났음.

   찾아보니

//출차하지 않은차 처리
for (String carNum : in.keySet()) {
    int limitM = TimeToMin("23:59");
    int useM = limitM - in.get(carNum);
    myRecords.put(carNum, myRecords.getOrDefault(carNum, 0) + useM);
    //in.remove(carNum); //출차 in에서 삭제해준다.
}

출차하지 않은 차 처리 할때 in.revove(carNum) 요놈이 문제였음. 

여기는 굳이 필요없는 라인이긴 했는데 넣어놨더니 문제일으킴. 

in Map의 KeySet으로 for문을 돌고있는데 remove 해주면 keySet이 변경되서 동시성 오류 발생한다.

반응형

+ Recent posts