자바 알고리즘 기초

JAVA 기초 알고리즘 - 개인정보 수집 유효기간 (문자열 split 사용으로 배열로 바꾸기)

들쮜 2023. 4. 30. 22:48

카카오 코딩 테스트 문제라고 해서 꽤나 어려울 줄 알았는데, 비교적 로직 자체는 간단해서 그냥 제출했다가 틀렸습니다를 보고 나서야 반례를 부랴부랴 넣은 문제였습니다.

파이썬으로 했다면 좀 더 반례를 세밀하게 찾았을 것 같은데 자바 언어 자체가 아직 익숙하지 않다보니 좀 더 놓치는 부분이 많게 되는 것 같아요..

개인정보 수집 만료일은 개인정보 수집 일자에서 유효기간을 더한 날 - 1일 이라는 것만 체크하고 그걸 오늘 날짜와 비교하기만 하면 되는데,

문제는 오늘 날짜의 연, 월, 일을 어떻게 분리해 낼 것인가 하는거였습니다.

다행히 파이썬과 마찬가지로 자바에서도 문자열에 split을 해주면 문자열을 쪼개어 배열로 만들 수 있었습니다.

정말 많이 사용하게 되는게 공백을 기준으로 자르는 문자열.split(" "); 인데요



terms와 privacies 배열을 보면 값들이 공백으로 나누어져있는 걸 알 수 있습니다.

이런 값들을 가져올 때 공백을 기준으로 split해주면 손 쉽게 값들을 가져올 수 있습니다.

문제는 today와 같이 문자열에서 “ . ” 으로 구분되어있는 문자열을 쪼개는건데요

파이썬에는 그냥 split(".") 으로도 됐던 것 같은데... 아닌가..

split안에는 정규식이 들어가기 때문에 . 하나만 넣으면 문자 하나 로 인식을 해버리기 때문에 split("[.]") 으로 구분자를 설정해주어야 제대로 분해하는 걸 볼 수 있습니다.


import java.util.*;

class Solution {
    public int[] solution(String today, String[] terms, String[] privacies) {
        int[] answer = {};
        List<Integer> result = new ArrayList<Integer>();
        // 1. today를 year, month, day로 나누기
        String[] today_date = today.split("[.]");
        int today_year = Integer.valueOf(today_date[0]);
        int today_month = Integer.valueOf(today_date[1]);
        int today_day = Integer.valueOf(today_date[2]);
        
        Map<String, Integer> expire_map = new HashMap();
        
        // 2. 영어별로 만료 기간 받아오기
        for(int i=0; i<terms.length; i++){
            String alpha = terms[i].split(" ")[0];
            int expire_date = Integer.valueOf(terms[i].split(" ")[1]);
            expire_map.put(alpha, expire_date);
        }
        
        // 3. privacies 만료되는 날짜 찾기
        
        for(int i=0; i<privacies.length; i++){
            String[] target_date = privacies[i].split(" ")[0].split("[.]");
            String target_aplha = privacies[i].split(" ")[1];
            
            int target_year = Integer.valueOf(target_date[0]);
            int target_month = Integer.valueOf(target_date[1]);
            int target_day = Integer.valueOf(target_date[2]);
            target_month += expire_map.get(target_aplha);
            target_day -= 1;
            // 만약 day를 줄였는데 0이 된다면 28로 바꾼뒤 month를 -1 추가로 시켜야함
            if (target_day ==0){
                target_day = 28;
                target_month -= 1;
            }
            if (target_month==0){
                target_month = 12;
                target_year -= 1;
            }
            // 만약 month가 12를 넘었으면 12의 나머지를 month로!
            if (target_month > 12){
            target_year += target_month/12;
            target_month %= 12;
            if(target_month == 0){
                target_month = 12;
                target_year -= 1;
            }
            }
            System.out.printf("%d, %d, %d\n", target_year, target_month, target_day);
            
            // 이제 오늘과 값 비교하기 (오늘보다 만료날짜가 작다면 answer에 넣어주기)
            if (target_year < today_year){
                result.add(i+1);
            }else if( target_year == today_year && target_month < today_month ){
                result.add(i+1);
            }else if( target_year == today_year && target_month == today_month && target_day < today_day){
                result.add(i+1);
            }
        }
        answer = new int[result.size()];
        for(int i=0; i<result.size(); i++){
            answer[i] = result.get(i);
        }
            return answer;
    }
}

이렇게 주어진 문자열에서 연, 월, 일을 잘 분리해서 가져올 수 있느냐!

그리고 연 월 일을 적절하게 증가, 감소시킬 수 있느냐를 묻는 문제였습니다