devFancy BE Developer

[Programmers] 150370. 개인정보 수집 유효기간

2023-10-05
devFancy

문제 링크

성능 요약

  • 메모리: 78.4 MB, 시간: 0.68 ms

구분

  • 코딩테스트 연습 > 스택/큐

Answer Code1(23.10.05)

/**
 * 개인정보 수집 유효기간
 * @param today 오늘 날짜 YYYY.MM.DD
 * @param terms 약관의 유효기간 (약관종류 유효기간) : 공백으로 구분, 유효기간은 개월수
 * @param privacies 수집된 개인정보 (날짜 약관종류) : 공백으로 구분
 * @return 파기해야할 개인정보의 번호 오름차순
 */
import java.util.*;

class Solution {
    public int[] solution(String today, String[] terms, String[] privacies) {
        int[] answer = {};
        Map<String, String> termsMap = new HashMap<>(); // key: 약관 종류, value: 유효 기간

        for(String term: terms) {
            String[] termSplit = term.split(" ");
            termsMap.put(termSplit[0], termSplit[1]);
        }

        Integer number = 1; // privacies의 번호
        List<Integer> result = new ArrayList<>();

        // 현재 총 날짜 수
        Integer todayTotalDate = getTotalDate(today, 0);
        for(String p : privacies) {
            String[] privateSplit = p.split(" ");
            // 개인별 날짜
            String privateDate = privateSplit[0];
            // 개인별 약관 종류
            String privateTerm = privateSplit[1];
            // 약관 개월수
            Integer termsMonth = Integer.valueOf(termsMap.get(privateTerm));

            // 기간 경과후 총 날짜 수
            Integer privateTotalDate = getTotalDate(privateDate, termsMonth) - 1;

            // 기간 경과후 날짜가 현재날짜보다 미만이면 폐기 대상
            if(privateTotalDate < todayTotalDate) {
                // 현재 당일은 아직 폐기 대상 아님
                // 유효기간 경과하여 폐기대상인 번호를 추가
                result.add(number);
            }
            // privacies의 번호 + 1
            number++;
        }
        answer = result.stream().mapToInt(Integer::intValue).toArray();
        return answer;
    }
    /**
     * (YYYY.MM.DD)을 총 날짜 수로 환산
     * @param strDate YYYY.MM.DD
     * @param termsMonth 약관 개월 수
     * @return 날짜로 환산한 총 날짜 수
     */
    private Integer getTotalDate(String strDate, Integer termsMonth) {
        String [] dateSplit = strDate.split("\\.");
        Integer year = Integer.valueOf(dateSplit[0]);
        Integer month = Integer.valueOf(dateSplit[1]) + termsMonth;
        Integer day = Integer.valueOf(dateSplit[2]);

        // 모두 일 수로 환산, 한 달은 28일
        return (year * 12 * 28) + (month * 28) + day;
    }
}

문제 풀이

조건) 모든 달은 28일 까지 있다고 가정

today: 오늘 날짜를 의미하는 문자열 → “YYYY.MM.DD

terms: 약관의 유효 기간을 담은 1차원 문자열 배열 → “약관 종류, 유효 기간

privacies : 수집된 개인정보의 정보를 담은 1차원 문자열 배열 → “날짜, 약관 종류

출력) 파기해야할 개인정보의 번호를 오름차순으로 1차원 정수 배열에 담아 return

  1. 약관의 종류별로 유효 기간을 취득하기 위해 약관의 유효 기간을 담는 termsMap으로 변환해준다.

    (key: 약관 종류, value: 유효 기간)

    Map<String, String> termsMap = new HashMap<>();

  2. 오늘 날짜를 총 날짜 수로 변환해준다.

    참고) 연월일을 총 날짜수로 변환하는 식: (연도 * 12개월 * 28일) + (월 * 28일) + 일

    Integer todayTotalDate = (today의 YYYY * 12 * 28) + (today의 MM * 28일) + (today의 DD)

  3. 개인정보 privacies 배열을 하나씩 확인해가며 약관이 유효한지 만료되었는지 확인한다.

    1. 배열 privacies에서 날짜약관종류를 분리하여 취득한다.
      • 공백으로 분리되어 있으므로 공백으로 자르면 인덱스 0날짜이며, 인덱스 1약관 종류가 된다.
      • String privateDate = privacies원소.split(” “)[0] // 날짜
      • String privateTerm = privacies원소.split(” “)[1] // 약관 종류
    2. 약관 종류로 Map에서 유효 기간을 취득한다.
      • Integer termsMonth = Integer.valueOf(termsMap.get(privateTerm)); A에 해당하는 유효 기간(달)을 갖는다.
    3. 날짜의 달에 유효기간 달 수를 더해준다.
      • Integer privateMonth = Integer.valueOf(privateDate.split(”\.”)[1]) + termsMonth
    4. 유효 기간 경과후 총 날짜 수를 구한다.
      • Integer privateTotalDate = (privateDate의 YYYY * 12 * 28) + (privateMonth * 28) + (privateDate의 DD)
    5. 계산된 전체 날짜 수를 비교하여 폐기 대상인지 확인한다.

      (유효 기간을 고려한 약관 날짜 수 < today의 총 날짜수) 이면, 폐기 대상이다.

      if( privateTotalDate < todayTotalDate) 폐기대상

      today 당일의 경우에도 아직 유효 기간이 지나지 않아 폐기 대상이 아니므로 today 미만으로 계산한다.

  • 결과) answer = result.stream().mapToInt(Integer::intValue).toArray();

    • result.stream(): result 리스트를 스트림으로 변환합니다. 스트림은 데이터의 연속적인 흐름을 나타내는 것으로, 다양한 연산을 수행할 수 있게 해줍니다.

    • mapToInt(Integer::intValue): mapToInt는 스트림의 각 요소에 대해 특정 함수를 적용하고, 그 결과를 정수로 매핑합니다. 여기서 Integer::intValue는 각 요소를 정수형으로 변환하는 함수입니다.

    • toArray(): 매핑된 결과를 배열로 변환합니다.

    • 따라서, result 리스트의 각 요소들이 정수로 변환되어 배열로 반환되며, 그 결과가 answer 변수에 할당됩니다. 이것은 함수의 반환 값으로 사용됩니다.

Review

  • 이전에 풀어봤지만 복습 겸 다시 한번 풀어봤다.

  • 이번에는 다양한 자바의 문법을 사용했고, 스트림을 사용해봤다.

  • 다시 봐도 문제의 흐름대로 잘 정리해두고 풀어야 풀 수 있는 문제였다.

  • 그리고 연월일을 총 날짜수로 변환하는 식은 꼭 기억해두자.

  • 정리하고 푸는데 은근히 시간을 많이 썼다.

Reference

  • https://gymdev.tistory.com/46

Comments

Index