Coding Test/programmers

[프로그래머스] 개인정보 수집 유효기간 c++

owls 2023. 1. 17. 13:07
728x90

문제 설명

오늘 날짜를 의미하는 문자열 today, 약관의 유효기간을 담은 1차원 문자열 배열 terms와 수집된 개인정보의 정보를 담은 1차원 문자열 배열 privacies가 매개변수로 주어집니다. 이때 파기해야 할 개인정보의 번호를 오름차순으로 1차원 정수 배열에 담아 return 하도록 solution 함수를 완성해 주세요.

제한 사항

  • today는 "YYYY.MM.DD" 형태로 오늘 날짜를 나타냅니다.
  • 1 ≤ terms의 길이 ≤ 20
    • terms의 원소는 "약관 종류 유효기간" 형태의 약관 종류와 유효기간을 공백 하나로 구분한 문자열입니다.
    • 약관 종류는 A~Z중 알파벳 대문자 하나이며, terms 배열에서 약관 종류는 중복되지 않습니다.
    • 유효기간은 개인정보를 보관할 수 있는 달 수를 나타내는 정수이며, 1 이상 100 이하입니다.
  • 1 ≤ privacies의 길이 ≤ 100
    • privacies[i]는 i+1번 개인정보의 수집 일자와 약관 종류를 나타냅니다.
    • privacies의 원소는 "날짜 약관 종류" 형태의 날짜와 약관 종류를 공백 하나로 구분한 문자열입니다.
    • 날짜는 "YYYY.MM.DD" 형태의 개인정보가 수집된 날짜를 나타내며, today 이전의 날짜만 주어집니다.
    • privacies의 약관 종류는 항상 terms에 나타난 약관 종류만 주어집니다.
  • today와 privacies에 등장하는 날짜의 YYYY는 연도, MM은 월, DD는 일을 나타내며 점(.) 하나로 구분되어 있습니다.
    • 2000 ≤ YYYY ≤ 2022
    • 1 ≤ MM ≤ 12
    • MM이 한 자릿수인 경우 앞에 0이 붙습니다.
    • 1 ≤ DD ≤ 28
    • DD가 한 자릿수인 경우 앞에 0이 붙습니다.
  • 파기해야 할 개인정보가 하나 이상 존재하는 입력만 주어집니다.

입출력 예

today terms privacies result
"2022.05.19" ["A 6", "B 12", "C 3"] ["2021.05.02 A", "2021.07.01 B", "2022.02.19 C", "2022.02.20 C"] [1, 3]
"2020.01.01" ["Z 3", "D 5"] ["2019.01.01 D", "2019.11.15 Z", "2019.08.02 D", "2019.07.01 D", "2018.12.28 Z"] [1, 4, 5]

풀이

find, substr를 사용하여 파싱함수를 만들어 year, month, day를 계산한 풀이이다.

#include <string>
#include <vector>
#include <map>

using namespace std;
void parse(string str, vector<int>& vec, const string& delimiter){
    int pos = 0;
    string token("");
    while( (pos = str.find(delimiter)) != string::npos ){
        token = str.substr(0, pos);
        str.erase(0, pos + delimiter.length());
        vec.push_back(stoi(token));
    }
    vec.push_back(stoi(str));
}

bool checkDay(int term, vector<int>& curDay, const vector<int>& todays){
    curDay[0] = curDay[0] + (curDay[1] + term ) / 12;
    curDay[1] = (curDay[1] + term) % 12;
    curDay[2] -= 1;
    if( curDay[2] == 0){
        curDay[1] -= 1;
        curDay[2] = 28;
    }
    if(curDay[1] == 0){
        curDay[0] -= 1;
        curDay[1] = 12;
    }

    for(int i = 0; i < 3; i++){
        if(curDay[i] < todays[i]){
            return true;
        }
        else if(curDay[i] > todays[i]){
            return false;
        }
    }
    return false;
}

vector<int> solution(string today, vector<string> terms, vector<string> privacies) {
    map<char, int> term;
    for(const auto& it : terms){
        char c = it[0];
        int n = stoi(it.substr(2, it.length() - 2));
        term[c] = n;
    }
    vector<int> todays;
    parse(today, todays, ".");
    vector<int> answer;
    for(int i = 0; i < privacies.size(); i++){
        int pos = privacies[i].find(" ");
        string str = privacies[i].substr(0, pos);
        string sterm= privacies[i].substr(pos+1, 1);
        vector<int> curday;
        parse(str, curday, ".");
        if(checkDay(term[sterm[0]], curday, todays)){
            answer.push_back(i+1);
        }
    }
    
    return answer;
}

 

다른 풀이

year, month, day를 각각 계산하지 않고, day로 모두 변환시켜 day 값으로 비교하는 풀이이다.

vector<int> solution3(string today, vector<string> terms, vector<string> privacies) {
    vector<int> answer;

    int cur = stoi(today.substr(0,4)) * 12 * 28 + (stoi(today.substr(5,2))-1) * 28 + stoi(today.substr(8,2));
    vector<int> term(26, 0);
    for(int i=0; i<terms.size(); i++) {
        int type = (int)terms[i][0] - 65;
        term[type] = stoi(terms[i].substr(2, terms[i].length()-2));
    }

    for(int i=0; i<privacies.size(); i++) {
        string s = privacies[i];
        int start = stoi(s.substr(0,4)) * 12 * 28 + (stoi(s.substr(5,2))-1) * 28 + stoi(s.substr(8,2));
        int period = term[(int)s[11] - 65];
        int end = start + 28*period - 1;
        if(end < cur) answer.push_back(i+1);
    }

    return answer;
}
728x90