해당 글을 포스트하는 이유는 문제를 풀면서 기존에 했던 생각과 바뀐 생각을 기록하여 잊지 않게하기 위함임.
프로그래머스에서 제공하는 해시 기본 문제
완주하지 못한 선수와 전화번호 목록을 풀때 너무 귀찮아서 정답을 봤더니 같은 언어로 완료 처리가 되지 않는다.........주의할 것ㅠ
1. 완주하지 못한 선수
2개의 배열이 주어지고 그 중 일치하지 않는 항목은 찾는 문제
String[] str1 = {"abc", "qwe", "zxc"};
String[] str2 = {"qwe", "abc"};
대충 이런식으로 정렬되지 않은 두 개의 배열에서 일치하지 않는 하나의 값을 return하는 문제였다.
처음 풀때 중점을 둔 부분은 for을 한 번만 도는것이였다.
내 첫 생각은 다음과 비슷했다. (너무 하기 싫어서 직접 안풀었음...)
Arrays.sort(str1);
Arrays.sort(str2);
for (int i=0; i<str1.length-1; i++) {
if (!str1[i].equlas(str2[i]){
return str[i];
}
}
return str[str1.length-1];
(블로그 글을 작성하면서 막 작성하는 코드라 오타 or 에러가 있을 수 있음)
이런식으로 정렬은 먼저 하고 긴 배열의 사이즈 -1 만큼 탐색하면서 일치하는지 검사 후 일치하지 않는 데이터를 리턴하는 형태였다.
그 중 다른 사용자들이 풀이 중 내가 생각한 최고는 이런 형태다.
HashMap<String, Integer> map = new HashMap<>();
for (int i=0; i<str1.length; i++) {
map.compute(str1[i], (k,v) -> v != null : null : 1);
if (i < str2.length) {
map.compute(str2[i], (k,v) -> v != null ? null : 1);
}
}
해당 코드는 하나의 map에 데이터가 없으면 1을 넣고 있으면 null을 넣는다.
그 결과 map의 value가 1이 되면 한번만 들어온 데이터가 되기 때문에 두 개의 배열 중 일치하지 않는 데이터이다.
내가 이 코드를 최고라고 생각한 이유는 다음과 같다.
1. map이기 때문에 이미 key값이 저장됐는지 검사하는 로직을 사용하기 쉬운데 compute를 이용해서 제거함. (나였으면 무조건 containsKey 사용했을듯...)
2. 사이즈가 다른 두개의 배열을 하나의 for문 안에서 해결함. (사이즈가 큰 배열을 메인으로 두고 작은배열은 if를 걸어서 해결)
3. 람다까지 사용하여 매우 깔끔함. (삼항연산자를 선호하지 않는데 compute와 결합되니 너무 보기 좋음.)
해당 문제를 보면서 공부한 것
HashMap<String, Integer> map = new HashMap<>();
map.put("a", map.getOrDefault("a", 0)); // a라는 key의 value를 반환하지만 값이 없으면 default를 리턴함.
map.compute("b", (k,v) -> v != null ? null : 1); // key값에 따라서 value를 리턴 후 반환
왜인지는 모르겠지만 일하면서 Map을 정말 조금 사용했다. 그것도 가장 기본적인 기능만...
자바의 기본부터 천천히 쌓아야겠다.
'Algorithm' 카테고리의 다른 글
그리디 - 큰 수 구하기 (0) | 2022.01.04 |
---|---|
종만북이 설명하는 알고리즘 풀이 순서 (0) | 2021.06.29 |
[C++] 소문자 대문자 변형 (0) | 2019.04.25 |
부분수열 (Subsequence) (0) | 2019.03.31 |
[C++] getline (0) | 2019.02.23 |