알고리즘/프로그래머스
프로그래머스(C++, JAVA) / level 2 : 주차 요금 계산
clean_h
2022. 4. 14. 00:39
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++ 실행 속도
728x90