programmers.co.kr/learn/courses/30/lessons/64065
로직은 쉬웠지만... 자바로 문자열 처리하는게 오랜만이라 시간이 좀 걸렸다.
로직
#2 코드 로직으로 적겠다.
-
s는 하나의 스트링형태로 되어있기 때문에 "{"와 "}"를 모두 제거하고, ","를 기준으로 분할하여 숫자들만 모아 하나의 list로 만든다.
-
숫자를 카운트 하여 카운트 정보를 Hashtable에 넣어준다(Hashtable<숫자, 카운트된 횟수>).
-
최종 리턴 값은 카운트된 횟수 기준으로 내림차순 정렬이 되어야하기 때문에 Hashtable을 순회하면서 (Hashtable 전체 길이 - 카운트된 횟수)를 index로하여 최종 리턴 리스트 answer에 숫자를 넣어준다.
-
예를 들면 s = "{{2},{2,1},{2,1,3},{2,1,3,4}}" 일 경우 hashtable의 길이는 4가 된다(숫자가 4종류이므로). 그리고 가장 카운트 횟수가 많은 2는 총 4번 출현하게 되고 가장 앞에 와야하기 때문에 index = 4 - 4 = 0이 된다.
-
코드
# 1
import java.util.*;
class Solution {
public int[] solution(String s) {
// make a dictionary for integer frequency
Hashtable<Integer, Integer> dictionary = new Hashtable<Integer, Integer>();
make_dictionary(dictionary, s.split("}"));
// initalize answer list with dictionary size
int N = dictionary.size();
int[] answer = new int[N];
// fill out the answer list with dictionary
for(Integer key : dictionary.keySet()){
int index = N - dictionary.get(key);
answer[index] = key;
}
return answer;
}
void make_dictionary(Hashtable<Integer, Integer> dictionary, String[] s){
for(String str : s){
for(String str_num : str.split(",")){
String tmp = str_num.replaceAll("\\{", "");
if(tmp.matches("([^\\s][0-9]*)")){
int num = Integer.parseInt(tmp);
int count = dictionary.getOrDefault(num, 0);
dictionary.put(num, count + 1);
}
}
}
}
void print_dictionary(Hashtable<Integer, Integer> dictionary){
Set<Integer> keys = dictionary.keySet();
for(Integer key : keys){
System.out.println(key + " : " + dictionary.get(key));
}
System.out.println(" ");
}
}
처음 썼던 코드... ㅎ 문자열 처리하는 부분이 살짝 더럽다...
가령 s = "{{2},{2,1},{2,1,3},{2,1,3,4}}" 일 경우 위의 코드는 첫 번쨰 for문에서 {2} {2,1} {2,1,3} {2,1,3,4} 단위로 벗겨낸 뒤 , 두 번째 for문에서 2 카운트, 2 1 카운트, 2 1 3 카운트... 이런 느낌이다.
사실 코드를 쓰는 중간 즈음에 그냥 다 잘라서 숫자 카운트 하면 된다는 걸 이중 for문을 쓰다가 알아버림.. 게다가 replaceAll()안에 여러 개의 패턴을 쓸 수 있다는 사실도 몰랐기 때문에 제출 이후 좀 더 깔끔하게 정리해보았다.
# 2
import java.util.*;
class Solution {
public int[] solution(String s) {
// make a dictionary for integer frequency
Hashtable<Integer, Integer> dictionary = new Hashtable<Integer, Integer>();
make_dictionary(dictionary, s.replaceAll("[}{]", "").split(","));
// initalize answer list with dictionary size
int N = dictionary.size();
int[] answer = new int[N];
// fill out the answer list with dictionary
for(Integer key : dictionary.keySet()){
int index = N - dictionary.get(key);
answer[index] = key;
}
return answer;
}
void make_dictionary(Hashtable<Integer, Integer> dictionary, String[] s){
for(String str : s){
if(str.matches("[^\\s]*")){
int num = Integer.parseInt(str);
int count = dictionary.getOrDefault(num, 0);
dictionary.put(num, count + 1);
}
}
}
void print_dictionary(Hashtable<Integer, Integer> dictionary){
Set<Integer> keys = dictionary.keySet();
for(Integer key : keys){
System.out.println(key + " : " + dictionary.get(key));
}
System.out.println(" ");
}
}
#1와 비교해서 가장 큰 차이는
-
make_dictionary()에 들어가기 전, replaceAll("[}{]")로 "{" 와 "}" 문자열을 제거해주고 split(",")으로 "," 기준 모든 스트링(스트링화된 숫자)들을 분할하여 하나의 리스트 안에 넣어주어 문자열 처리과정을 한 코드로 정리하였다.
-
모든 숫자들을 하나의 리스트 안에 넣고 한 번에 처리할 수 있게 만들어서 for문이 하나로 줄었다. 아아싸
참고 할 것!!
🧡 Integer.parseInt vs Integer.valueOf
parseInt vs valueOf [참고]
💛 s.split(), s.trim(), s.replaceAll()
[구글링하면 다 나옴]
💚 Hashtable
Hashtable 오라클 공식 문서 [참고]
💙 java regex 정리
- import java.util.regex.Pattern → Pattern.matches(pattern, str);
- import java.util.* → str.matches(pattern);
- regex meta character에 있는 문자의 경우({}, [], s, +, ...) \\를 붙여 사용한다. 예를들면 문자 "{" 는 "\\{" 로 패턴에 넣어주어야 한다. 삽질한 이유 중 하나
regex에서 meta character 포함된 문자 처리 방법 (stackoverflow) [참고2]
💜 java가 String을 처리하는 법
'코테 준비' 카테고리의 다른 글
[프로그래머스] 게임 맵 최단거리 (0) | 2020.10.22 |
---|---|
[프로그래머스/2019 카카오 개발자 겨울 인턴십/Java & python] 징검다리 건너기 (0) | 2020.10.20 |
[프로그래머스 - 카카오] 인형뽑기 - Java (0) | 2020.10.19 |
[프로그래머스 - 카카오] 크레인 인형뽑기 게임 - Java (0) | 2020.10.19 |
[프로그래머스] 스킬트리- Java (0) | 2020.10.16 |