import java.util.HashMap;
import java.util.HashSet;
public class Solution {
// 아이디 추천
// S(3 ~ 6 길이 영 소문자) + N(0 ~ 6 길이 숫자) 조합의 아이디를 추천한다.
public static String solution(String[] registered_list, String new_id) { // 등록된 아이디 배열, 신규 아이디
String answer = "";
int registeredStrEndIdx = 0; // 등록된 아이디의 S + N 조합에서 S의 마지막 인덱스를 담을 변수
int newStrEndIdx = 0; // 신규 아이디의 S + N 조합에서 S의 마지막 인덱스를 담을 변수
String tempStr = ""; // S 부분을 담을 변수
int tempNum = 0; // N 부분을 담을 변수
int recommendNum = 0; // 신규 아이디가 이미 등록되어 있을 경우 추천할 숫자
HashMap<String, HashSet<Integer>> hmHs = new HashMap<>();
// STEP 1. 등록된 아이디 체크하며 HashMap<String, HashSet<Integer>> 구조로 key와 value 담기
for (String str : registered_list) { // 등록된 아이디 체크
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) >= '0' && str.charAt(i) <= '9') { // S + N 조합에서 N 시작(숫자 시작) 인덱스 확인
registeredStrEndIdx = i - 1; // 영 소문자로 구성된 문자열 S의 마지막 인덱스
break;
}
}
if (registeredStrEndIdx == 0) { // strEndIdx가 그대로라면! 즉, 등록된 이 아이디가 문자열로만 이루어져 있다면(S)
if (!hmHs.containsKey(str)) { // 이미 key 값으로 갖고있는 문자열 S인지 체크
hmHs.put(str, new HashSet<Integer>()); // 없다면 문자열 S를 key로 넣고 value값을 담을 HashSet 생성
hmHs.get(str).add(0); // 최초 card=[0]
}
} else { // 등록된 이 아이디가 영 소문자 문자열 + 숫자라면(S + N)
tempStr = str.substring(0, registeredStrEndIdx + 1); // S
tempNum = Integer.parseInt(str.substring(registeredStrEndIdx + 1, str.length())); // N
if (!hmHs.containsKey(tempStr)) { // 이미 key 값으로 갖고있는 문자열 S인지 체크
hmHs.put(tempStr, new HashSet<Integer>());
hmHs.get(tempStr).add(tempNum);
} else {
hmHs.get(tempStr).add(tempNum);
}
}
registeredStrEndIdx = 0; // 다음 등록된 아이디 확인 전 초기화
}
// hmHs => {ace=[16, 17, 13, 14], banker=[0], card=[0]}
// STEP 2. 신규 아이디가 사용 가능한지 확인, 사용 불가하다면 아이디 추천받기
for (int i = 0; i < new_id.length(); i++) {
if (new_id.charAt(i) >= '0' && new_id.charAt(i) <= '9') { // 숫자 범위라면
newStrEndIdx = i - 1;
break;
}
}
if (newStrEndIdx == 0) { // newStrEndIdx가 그대로라면! 즉, 신규 아이디가 문자열로만 이루어져 있다면(S)
if (!hmHs.containsKey(new_id)) { // 신규 아이디이자, 아이디의 S가 등록된 아이디의 key로 존재하지 않아 그대로 사용 가능하다면
answer = new_id; // 신규 아이디 S를 그대로 사용하도록 함
} else { // 신규 아이디이자, 아이디의 S가 이미 등록되어 있다면
HashSet<Integer> tempHs = hmHs.get(new_id); // 뒤에 붙일 숫자 추천을 위해 HashSet 가져오기 // 이 경우 null이 담길 수 없음
// 1. HashSet은 null 값을 저장할 수 있다. 2. null과 isEmpty는 다르다.
while(true) { // 숫자 추천을 위해 확인 반복 // 이 경우 신규 아이디가 이미 등록되어 있는 경우이므로 tempHs에는 null이 담겨있을 수 없기 때문에 null인 경우 무시
if (tempHs.contains(recommendNum)) { // 0부터 체크 // 해당 번호가 있다면
recommendNum++; // 있다면 1 증가
} else { // 0부터 체크 // 해당 번호가 없다면
if (recommendNum == 0) {
answer = new_id; // S 그대로 사용하도록 함
} else {
answer = new_id + Integer.toString(recommendNum); // S + 추천 숫자
}
break;
}
}
}
} else { // 신규 아이디가 영 소문자 문자열 + 숫자라면(S + N)
tempStr = new_id.substring(0, newStrEndIdx + 1); // S
tempNum = Integer.parseInt(new_id.substring(newStrEndIdx + 1, new_id.length())); // N
HashSet<Integer> tempHs = hmHs.get(tempStr); // 없으면 HashSet에 null이 담긴다.
while(true) { // 숫자 추천을 위해 확인 반복
if (tempHs == null) { // HashSet은 null 값을 저장할 수 있기 때문에 isEmpty를 써선 안된다. // N을 그대로 사용 가능하다면
answer = tempStr + Integer.toString(tempNum); // S + N
break;
} else {
if (tempHs.contains(tempNum)) { // 신규 아이디와 숫자가 이미 존재한다면
tempNum++; // 숫자 1 증가
} else { // 사용 가능한 숫자라면
answer = tempStr + Integer.toString(tempNum); // S + N 또는 S + 추천 숫자
break;
}
}
}
}
return answer;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] registered_list = {"card", "ace13", "ace16", "banker", "ace17", "ace14"}; // 배열 길이 1 ~ 100000
String new_id = "ace15";
System.out.println(solution(registered_list, new_id)); // ace15 // S(3 ~ 6 길이 영 소문자) + N(0 ~ 6 길이 숫자) 조합의 아이디 추천
}
}
1. HashSet은 null 값을 저장할 수 있다.
2. null과 isEmpty는 다르다. (null : 인스턴스가 생성되지 않은 상태, isEmpty : 인스턴스는 생성되었으나 비어있는 상태)
HashMap<String, HashSet<Integer>> hmHs = new HashMap<>();
HashSet<Integer> testOneHs = hmHs.get("test"); // 이 경우 isEmpty가 아닌 null
HashSet<Integer> testTwoHs = new HashSet<Integer>(); // 이 경우 null이 아닌 isEmpty
프로그래머스 아이디 추천 문제 풀이 Java
'Java > 프로그래머스' 카테고리의 다른 글
[Java] 프로그래머스 [Level-3] 자물쇠와 열쇠 (1) | 2022.11.28 |
---|---|
[Java] 프로그래머스 [TEST] Uncompress String (0) | 2022.11.28 |
[Java] 프로그래머스 [TEST] Anagram (0) | 2022.11.28 |
[Java] 프로그래머스 [Level-3] 등굣길 (0) | 2022.11.28 |
[Java] 프로그래머스 [Level-3] 단속카메라 (0) | 2022.11.28 |