성능 요약
- 메모리: 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
-
약관의 종류별로 유효 기간을 취득하기 위해 약관의 유효 기간을 담는
terms
를 Map으로 변환해준다.(key: 약관 종류, value: 유효 기간)
Map<String, String> termsMap = new HashMap<>();
-
오늘 날짜를 총 날짜 수로 변환해준다.
참고) 연월일을 총 날짜수로 변환하는 식: (연도 * 12개월 * 28일) + (월 * 28일) + 일
Integer todayTotalDate = (
today
의 YYYY * 12 * 28) + (today
의 MM * 28일) + (today
의 DD) -
개인정보
privacies
배열을 하나씩 확인해가며 약관이 유효한지 만료되었는지 확인한다.- 배열 privacies에서
날짜
와약관종류
를 분리하여 취득한다.- 공백으로 분리되어 있으므로 공백으로 자르면 인덱스
0
은 날짜이며, 인덱스1
은 약관 종류가 된다. - String privateDate = privacies원소.split(” “)[0] // 날짜
- String privateTerm = privacies원소.split(” “)[1] // 약관 종류
- 공백으로 분리되어 있으므로 공백으로 자르면 인덱스
- 약관 종류로 Map에서 유효 기간을 취득한다.
- Integer termsMonth = Integer.valueOf(termsMap.get(privateTerm)); A에 해당하는 유효 기간(달)을 갖는다.
- 날짜의 달에 유효기간 달 수를 더해준다.
- Integer privateMonth = Integer.valueOf(privateDate.split(”\.”)[1]) + termsMonth
- 유효 기간 경과후 총 날짜 수를 구한다.
- Integer privateTotalDate = (privateDate의 YYYY * 12 * 28) + (privateMonth * 28) + (privateDate의 DD)
-
계산된 전체 날짜 수를 비교하여 폐기 대상인지 확인한다.
(유효 기간을 고려한 약관 날짜 수 < today의 총 날짜수) 이면, 폐기 대상이다.
if( privateTotalDate < todayTotalDate) 폐기대상
today 당일의 경우에도 아직 유효 기간이 지나지 않아 폐기 대상이 아니므로 today 미만으로 계산한다.
- 배열 privacies에서
-
결과) 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