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

[프로그래머스 2023 KAKAO BLIND RECRUITMENT] 개인정보 수집 유효기간

by 선서니 2023. 6. 17.

 

[문제 바로가기]👇

 

프로그래머스

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

programmers.co.kr

 

프로그래머스에서 코딩 테스트를 보는 회사가 많은데, 프로그래머스 환경에서 구현 문제를 푸는데 시간이 오래 걸려서 구현 문제 위주로 연습을 하려고 한다

 

💡풀이💡

1. 약관 별 유효기간 데이터 map 생성

주어진 terms 배열의 데이터를 파싱해서 빠르게 약관 별 유효기간을 찾기 위해 Map 형태로 만들었다.

 

2. 개인 정보 파기 날짜 계산

자바의 Calendar 클래스를 이용해 파기 날짜를 계산

주어진 today 변수와 파기 날짜를 비교해 파기 여부를 확인해 파기해야 하는 개인정보 번호 저장

 

 

전체 코드

import java.io.*;
import java.util.*;
import java.text.*;


class Solution {
    public int[] solution(String today, String[] terms, String[] privacies) throws Exception {
        // 1. 약관 별 유효기간 데이터 map 생성
        Map<String, Integer> termsMap = new HashMap<>(); // 약관 종류 : 유효기간(달)
        for(int i=0; i<terms.length; i++) {
            String[] temp = terms[i].split(" ");
            termsMap.put(temp[0], Integer.parseInt(temp[1]));
        }
        
        // 2. 개인 정보 파기 날짜 계산
        ArrayList<Integer> removedFiles = new ArrayList<>();
        for(int i=0; i<privacies.length; i++) {
            String[] temp = privacies[i].split(" "); // 날짜, 약관 종류
            String dateOfInfo = temp[0];
            String termType = temp[1];
            
            int term = termsMap.get(termType); // 유효 기간
            String removedDate = calDate(dateOfInfo, term); // 파기 날짜 계산
            if(isRemoved(today, removedDate)) removedFiles.add(i+1); // 파기 여부 확인
        }
        
        int[] answer = new int[removedFiles.size()];
        for(int i=0; i<answer.length; i++) {
            answer[i] = removedFiles.get(i);
        }
        Arrays.sort(answer);
        
        return answer;
    }
    
    // 파기 날짜 계산 
    public String calDate(String startDate, int month) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd");
        Calendar cal = Calendar.getInstance();
        
        Date date = dateFormat.parse(startDate);
        cal.setTime(date);
        
        cal.add(Calendar.MONTH, month); // 유효기간 만큼 더하기
        cal.add(Calendar.DATE, -1); // 유효기간 하루 전까지만 보관 가능 하기 때문에 하루 빼주기
        
        if(cal.get(Calendar.DATE) > 28) { // 모든 달은 28일까지만 있음
            cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), 28);
        }
        
        return dateFormat.format(cal.getTime());
    }
    
    // 파기 해야 하는지 확인
    public boolean isRemoved(String today, String removedDate) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd");
        Date to = dateFormat.parse(today);
        Date remove = dateFormat.parse(removedDate);
        
        return to.after(remove); // 파기날짜 보다 오늘이 더 크면 true(파기 날짜가 지났을 때)
    }
}

Calendar 클래스를 문제를 풀 때 다뤄본게 처음이어서 익숙하지 않았다.

그래서 사용했던 내용들을 조금 정리해봤다.

 

- Calendar 클래스, Date 클래스 모두 java.util 패키지 안에 있음

- Calendar.add() :: Calendar 필드의 값에서 amount 만큼 더하거나 뺄 수 있음. 빼고 싶다면 amount 앞에 -(마이너스)를 붙여서 파라미터로 전달하기

 

다른 풀이

문제를 풀기 위해 개인정보 보관 유효기간 보다 오늘 날짜가 같거나 큰지만 확인하면 됨!

 

import java.io.*;
import java.util.*;
import java.text.*;


class Solution {
   public int[] solution(String today, String[] terms, String[] privacies) {
        List<Integer> answer = new ArrayList<>();
        Map<String, Integer> termMap = new HashMap<>();
        int date = getDate(today); // 날짜를 일로 변환

        for (String s : terms) {
            String[] term = s.split(" ");

            termMap.put(term[0], Integer.parseInt(term[1]));
        }
        for (int i = 0; i < privacies.length; i++) {
            String[] privacy = privacies[i].split(" ");

            // 일로 변환한 개인정보의 유효기간 계산해 오늘 날짜와 비교(일로 변환)
            if (getDate(privacy[0]) + (termMap.get(privacy[1]) * 28) <= date) {
                answer.add(i + 1);
            }
        }
        return answer.stream().mapToInt(integer -> integer).toArray();
    }

    private int getDate(String today) {
        String[] date = today.split("\\.");
        int year = Integer.parseInt(date[0]);
        int month = Integer.parseInt(date[1]);
        int day = Integer.parseInt(date[2]);
        return (year * 12 * 28) + (month * 28) + day;
    }
}

 

주의할 점!

자바에서는 String을 split 할 때, .(점)을 문자열로 . 으로 하면 원하는 대로 split이 되지 않는다. 

split 함수의 파라미터 타입이 String이 아니라 정규식이기 때문에 .(점)을 입력할 경우 임의이 모든 문자열을 뜻하기 때문에 예상과 다른 결과가 나오게 된다.

 

원하는 대로 .(점)으로 split을 하기 위해서는 이스케이프처리를 해서 사용해야한다.

이스케이프는 \\(역슬래시) 두번으로 처리할 수 있다.

String fullDate = "2022.05.19"
String[] date = fullDate.split("\\."); // [2022, 05, 19]

 

 

참고자료

자바 Calendar 클래스를 이용한 날짜 계산

 

[Java] 날짜 계산 방법(년, 월, 일 더하고 빼는 방법)

SimpleDateFormat, Calendar 클래스를 이용하여 특정 날짜에서 더하거나 뺀 날짜를 구할 수 있다. import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class DateAdd { public static void main(Strin

junghn.tistory.com

 

자바 날짜 비교하기

 

[JAVA] 날짜 비교하기(Date, Calendar, LocalDate, LocalDateTime)

JAVA 버전에 따라 날짜 비교하는 방법이 다릅니다. JAVA8 이전 1. Date java.util.Date 클래스를 이용하여 날짜를 비교할 수 있습니다. public boolean after(Date when) - 주어진 날짜가 매개변수로 전달받은 날짜

hajoung56.tistory.com

 

자바 .(점)으로 split 하기

 

[Java] split 점(.)으로 하기

자바에서 split을 .으로 하면 되지 않는다 예를 들면 String date = "2021.02.04"; String[] arr = date.split("."); 요렇게 하면 split이 되지 않는다 split을 .으로 하기 위해선 String[] arr = date.split("[.]"); or String[] arr =

living-only-today.tistory.com

 

댓글