알고리즘 테스트 공부

개인정보 수집 유효기간

&u_na& 2023. 9. 2. 23:13
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

class Solution {
    public List<Integer> solution(String today, String[] terms, String[] privacies) {
        int dayForM = 28;
        int todayY = Integer.parseInt(today.substring(0,4));
        int todayM = Integer.parseInt(today.substring(5,7));
        int todayD = Integer.parseInt(today.substring(8,10));

        int totalD = (todayY*dayForM*12) + (todayM*28) + todayD;
        List<Integer> answerArr = new ArrayList<>();
        HashMap<Character,Integer> termsMap = new HashMap<>();
        for(String term : terms){
            char termO = term.charAt(0);
            int termM = Integer.parseInt(term.substring(2));
            termsMap.put(termO,termM);
        }
        for(int i=0; i<privacies.length; i++){
            char privacyO = privacies[i].charAt(11);
            int privacyY = Integer.parseInt(privacies[i].substring(0,4));
            int privacyM = Integer.parseInt(privacies[i].substring(5,7));
            int privacyD = Integer.parseInt(privacies[i].substring(8,10));
            int totalPrivacyD = (privacyY*12*dayForM) + (privacyM*dayForM) + privacyD;
            int termM = termsMap.get(privacyO);
            int termDay = termM * dayForM;
            if(totalPrivacyD+termDay <=totalD){
                answerArr.add(i+1);
            }
        }

        return answerArr;
    }
}
class Solution {
    public int[] solution(String today, String[] terms, String[] privacies) {
       
        int cnt = intDay(today);
        
        String[] p1 = new String[privacies.length];
        int[] p2 = new int[privacies.length];
        int pLen = privacies.length;
        String tmp = "";
        
        for(int i=0; i<pLen; i++) {
        	p1[i] = privacies[i].split(" ")[1];
        	tmp = privacies[i].split(" ")[0];
        	p2[i] = intDay(tmp);
        }

        
        String[] t1 = new String[terms.length];
        int[] t2 = new int[terms.length];
        int tLen = terms.length;
        
        for(int i=0; i<tLen; i++) {
        	t1[i] = terms[i].split((" "))[0];
        	tmp = terms[i].split(" ")[1];
        	t2[i] = (Integer.parseInt(tmp)*28);
        }        
        
                
        for(int i=0; i<tLen; i++) {
        	for(int j=0; j<pLen; j++) {
        			if(t1[i].equals(p1[j])) {
        				p2[j] += t2[i];        				
        			}
        	}
        }
        
        List<Integer> answer = new ArrayList<>();
        
        for(int i=0; i<pLen; i++) {
        	if(p2[i]<cnt) {
        		answer.add(i+1);        
        	}
        		
        }        
        
        int[] ans = new int[answer.size()];
        
        for(int i=0; i<answer.size(); i++) {
        	ans[i] = answer.get(i);
        }
        
        return ans;
    }
    
    int intDay(String str) {
    	String tooday = str.replace(".", "");
        int year = Integer.parseInt(tooday.substring(2,4));
        int month = Integer.parseInt(tooday.substring(4,6));
        int day = Integer.parseInt(tooday.substring(6,8));
        return year*12*28 + month*28 + day;
    }
}

[풀이]

약관의 유효기간이 지나서 파기해야할 개인정보 번호를 구해야 한다.

  •  today   : 오늘 날짜를 의미하는 문자열
  •  terms  : 약관의 유효기간을 담은 1차원 문자열 배열
  •  privacies  : 수집된 개인정보의 정보를 담은 1차원 문자열 배열
  1. 약관의 종류별로 유효기간을 취득하기위해 약관 정보  terms  Map 으로 변환해준다. 
    (key : 약관 종류, value : 유효기간)
    Map<String, String> termsMap = new HashMap<>();
  2. 오늘 날짜를 총 날짜수로 변환해준다.
    Integer todayTotalDate = (  today 의 YYYY * 12 * 28) + ( today 의 MM * 28) +  today 의 DD
    약관이 유효한지 날짜를 확인하기위해 문자열(YYYY.MM.DD)을 Date 등으로 변환하거나 연, 월, 일을 따로 확인하는 방법보다 전체 날짜 수를 계산하는 방식을 사용했다.
    문제에서 한 달은 28일으로 주어지고 있으며, 약관의 유효기간은 달 수로 주어지기 때문에 유효기간을 고려했을때 연도 환산도 필요해져 버리기 때문이다. 그래서 다음과 같이 날짜 수로 변경하여 계산했다.
    ※ 연월일을 총 날짜수로 변환하는 식 :  (연도 * 12개월 * 28일) + (월 * 28일) + 일 
  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));
    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 미만으로 계산한다.

 

 

/**
 * 개인정보 수집 유효기간
 * @param today 오늘 날짜 YYYY.MM.DD
 * @param terms 약관의 유효기간 (약관종류 유효기간) : 공백으로 구분, 유효기간은 개월수
 * @param privacies 수집된 개인정보 (날짜 약관정보) : 공백으로 구분
 * @return 파기해야할 개인정보의 번호 오름차순
 */
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; // 기간이므로 -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;
}