본문 바로가기
알고리즘/프로그래머스

프로그래머스(C++, JAVA) / level 2 : 주차 요금 계산

by clean_h 2022. 4. 14.
728x90

level 2 : 주차 요금 계산

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

 

코딩테스트 연습 - 주차 요금 계산

[180, 5000, 10, 600] ["05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT", "07:59 5961 OUT", "07:59 0148 IN", "18:59 0000 IN", "19:09 0148 OUT", "22:59 5961 IN", "23:00 5961 OUT"] [14600, 34400, 5000]

programmers.co.kr

 

🎯 코드(C++)

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <unordered_map>
#include <map>

using namespace std;

int bTime, bFee, uTime, uFee;

int time(string in, string out){
    int time = 0;
    time = (stoi(out.substr(0,2)) - stoi(in.substr(0,2)))*60 + (stoi(out.substr(3,2)) - stoi(in.substr(3,2)));
    cout << "time : "<< time << "\n";
    return time; 
}

int fee(int t){
    int num = bFee;
    if(bTime < t){
        num += (t-bTime)/uTime * uFee;
        if((t-bTime)%uTime!=0){
            num += uFee;
        }
    }
    
    cout << "fee : " << num << "\n";
    
    return num; 
}


vector<int> solution(vector<int> fees, vector<string> records) {
    vector<int> answer;
    bTime = fees[0]; bFee = fees[1]; uTime = fees[2]; uFee = fees[3];
    
    unordered_map<int, string> IN;
    map<int, int> mapTime;
    for(int i=0; i<records.size(); i++){
        stringstream ss(records[i]);
        string t, IO;
        int number;
        ss >> t >> number >> IO;
        if(IO == "IN"){
            IN[number] = t;
        }
        else{
            mapTime[number] += time(IN[number], t);
            IN[number] = "";
        }
    }
    
    for(auto m : IN){
        if(m.second != ""){
            mapTime[m.first] += time(IN[m.first], "23:59");
        }
    }
    
    for(auto m : mapTime){
        answer.push_back(fee(m.second));
    }
    
    
    return answer;
}

 

🎯 코드(JAVA)

import java.util.*;

class Solution {
    public int bTime, bFee, uTime, uFee;
    
    public int time(String in, String out){
        int t = 0;
        String[] iSplit = in.split(":");
        String[] oSplit = out.split(":");
        t = (Integer.parseInt(oSplit[0])- Integer.parseInt(iSplit[0]))* 60 + (Integer.parseInt(oSplit[1])- Integer.parseInt(iSplit[1]));
        
        return t;
    }
    
    public int fee(int t){
        int f = bFee;
        
        if(bTime < t){
            f += ((t-bTime)/uTime)*uFee;
            if((t-bTime)%uTime!=0){
                f += uFee;
            }
        }
        System.out.println("fee : " + f);
        return f;
    }
    
    public int[] solution(int[] fees, String[] records) {
        int[] answer = {};
        bTime = fees[0]; bFee = fees[1]; uTime = fees[2]; uFee = fees[3];
        
        HashMap<String, String> In = new HashMap<>();
        Map<String, Integer> mapTime = new TreeMap<>();
        for(int i=0; i<records.length; i++){
            String[] ss = records[i].split(" ");
            if(ss[2].equals("IN")){
                In.put(ss[1], ss[0]);
            }
            else{
                mapTime.put(ss[1], mapTime.getOrDefault(ss[1], 0) + time(In.get(ss[1]), ss[0]));
                In.remove(ss[1]); //제거
            }
            
        }
        
        for(HashMap.Entry<String, String> e : In.entrySet()){
            mapTime.put(e.getKey(), mapTime.getOrDefault(e.getKey(), 0) + time(e.getValue(), "23:59"));
        }
        
        answer = new int[mapTime.size()];
        
        int i = 0;
        for(Map.Entry<String, Integer> e : mapTime.entrySet()){
            System.out.println(e.getValue());
            answer[i] = fee(e.getValue());
            i++;
        }
        
        return answer;
    }
    
}

 

🎯 설명

 

  • HashMap으로 선언한 IN에 입차한 차량을 차량번호, 시각을 저장한다. 
  • Map으로 선언한 mapTime에 챠량의 누적 주차시간을 저장한다.(이때 hashmap으로 선언하지 않은 이유는 hashmap은 정렬되지 않기 때문이다. 차량 번호가 작은 자동차부터 출력하기 때문, C++: map, Java: TreeMap)
  • time함수는 주차된 시간을 반환하고, fee함수는 주차 요금을 반환한다.
  • 차량이 출차하면 IN에서 입차한 시각을 찾아 주차되어있던 시간을 계산하여 mapTime에 저장한다.
  • 이후 입차는 되었지만 출차는 되지 않은 차량을 구하여 23:59에 출차된 것으로 간주하고 누적 주차시간을 구한다.
  • 모든 차량의 누적 주차 시간을 구한 이후 차량 번호가 작은 자동차부터 요금을 계산하여 answer에 저장한다.

 

 

JAVA, C++(문자열 나누기, split)

  • C++: stringstream 사용
stringstream ss(records[i]);
string t, IO;
int number;
ss >> t >> number >> IO;
  • JAVA: split 사용
String[] ss = records[i].split(" ");

 

JAVA, C++(문자열 나누기, substr)

  • C++: substr
time = (stoi(out.substr(0,2)) - stoi(in.substr(0,2)))*60 + (stoi(out.substr(3,2)) - stoi(in.substr(3,2)));
  • JAVA: substr
String[] iSplit = in.split(":");
String[] oSplit = out.split(":");
t = (Integer.parseInt(oSplit[0])- Integer.parseInt(iSplit[0]))* 60 + (Integer.parseInt(oSplit[1])- Integer.parseInt(iSplit[1]));

문자열을 나눌때 C++보다 Java가 훨씬 편하다.

C++에서 사용하는 stringstream은 공백은 편하게 나눌수 있지만 다른 기호로 나누어져있으면 쉽지 않다.

하지만 C++에서도 getline을 이용하여 split하는 방법이 존재한다. 

 

JAVA, C++(map 반복문)

  • C++: auto
    for(auto m : IN){
        if(m.second != ""){
            mapTime[m.first] += time(IN[m.first], "23:59");
        }
    }
  • JAVA: Map.Entry
        for(HashMap.Entry<String, String> e : In.entrySet()){
            mapTime.put(e.getKey(), mapTime.getOrDefault(e.getKey(), 0) + time(e.getValue(), "23:59"));
        }

C++은 auto로 자동으로 변수를 지정해주어 first와 second로 key값과 value값을 출력 가능하다.

Java는 Entry를 이용하여 map의 요소를 하나씩 가져오게 된다.

 

JAVA, C++(map, key값 존재확인)

  • C++: 배열로 접근
mapTime[number] += time(IN[number], t);
  • JAVA: getOrDefault()
mapTime.put(ss[1], mapTime.getOrDefault(ss[1], 0) + time(In.get(ss[1]), ss[0]));

C++은 기본으로 값이 0으로 지정되어있지만 Java는 기본적으로 값이 지정되어있지 않다.

그래서 Java는 Value값이 없다면 가져오지 못한다. 따라서 getOrDefault(key, 0)으로 값이 이미 있다면 value값을 값이 없다면 0으로 반환한다.

 

JAVA, C++ 실행 속도

java / C++ 실행속도 차이

728x90

댓글