일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Android
- androidstudio
- bitmap
- BOJ
- Canvas
- CS
- Database
- DBeaver
- DP
- Ecilpse
- Eclipse
- firebase
- git
- github
- GooglePlayServices
- gradle
- IDE
- IntelliJ
- java
- json
- kotlin
- level2
- linux
- mariadb
- MYSQL
- Paint
- permission
- python
- Sorting
- sourcetree
will come true
[프로그래머스 / Level1] 로또의 최고 순위와 최저 순위 (Java) 본문
문제
https://programmers.co.kr/learn/courses/30/lessons/77484#fn1
핵심 키워드
- 두 배열 간의 요소 비교
- 배열 포함 여부 확인
- binarySearch()
- anyMatch()
- contains()
풀이
- int[] lottos : 민우가 구매한 로또 번호를 담은 배열
- int[] win_nums : 당첨 번호를 담은 배열
- 두 배열을 비교하여 최저 순위 계산
로또 번호는 1~45 사이의 값, lottos에서 번호를 알 수 없는 것은 그대로 0으로 둔채, 현재 상태에서 (0을 제외한) lottos의 요소와 win_numbers의 요소가 매칭하는 개수를 확인한다. => 최저 순위 - lottos 배열에서 0인 값들을 'lottos 배열에 존재하지 않는 당첨번호'의 값으로 매칭해서 최고 순위 계산
lottos와 win_numbers의 길이는 무조건 같기 때문에, win_numbers에서 값을 정답으로 대체할 수 있는 0의 숫자만 구해서 '원래 매칭되던 값 개수' + '0개수'을 수행하면 최대 매칭 개수를 구할 수 있다. - 순위는 '7-매칭되는숫자개수'로 하되, 매칭되는 숫자가 1개 이하일 경우는 6등으로 통일한다.
ex) 매칭되는 숫자 : 6개 => 7-6 = 1등
매칭되는 숫자 : 5개 => 7-5 = 2등
매칭되는 숫자 : 1개 => 7-1 = 6등,
매칭되는 숫자 : 0개 => 7-0 = 최저순위가 6등이므로 6등으로 통일. - 최고 순위, 최저 순위를 배열에 담아서 반환.
코드
import java.util.Arrays;
//로또의 최고 순위와 최저 순위
public class Solution {
public int[] solution(int[] lottos, int[] win_nums) {
int[] answer = new int[2];
int matchCnt = 0;
int zeroCnt = 0;
Arrays.sort(lottos);
Arrays.sort(win_nums);
// 최저 순위
for(int lotto : lottos) {
if(Arrays.binarySearch(win_nums, lotto) >= 0)
matchCnt++;
if(lotto == 0)
zeroCnt++;
}
answer[1] = Math.min(7-matchCnt, 6);
// 최고 순위
answer[0] = Math.min(7-(matchCnt + zeroCnt), 6);
return answer;
}
}
배열에 특정 값이 존재하는지 포함 여부 체크
1. for문
반복문을 통해 배열의 요소를 순회, 요소와 key값을 하나씩 비교하며 key값과 일치하는 값이 존재하는지 확인한다.
public static void main(String[] args) {
int[] lottos = { 44, 1, 0, 0, 31, 25 };
int[] win_nums = { 31, 10, 45, 1, 6, 19 };
int match = 0;
for(int lotto : lottos) {
for(int win_num : win_nums) {
if(lotto == win_num) {
match++;
break;
}
}
}
System.out.printf("번호가 %d개 일치합니다. %d등 당첨!", match, Math.min(7-match, 6));
}
번호가 2개 일치합니다. 5등 당첨!
2. binarySearch()
이진탐색 메서드를 사용해 정렬된 배열에서 key값을 검색한다. key값 검색에 성공하면 해당 값이 존재하는 위치(index >= 0)를 반환하고, key값 검색에 실패하면 삽입 포인트(index < 0)를 반환한다.
*삽입 위치(insertion point) : 배열에 key값이 삽입된다면 어느 위치(index)에 들어와야 할지 알려준다. 탐색 실패 시 음수값을 반환하는데 이 음수값을 -(index)-1 하면 양수 삽입위치를 알 수 있다.
binarySearch() 메서드는 반드시 정렬된 배열에 사용해야한다. 이진 탐색은 배열요소-key값 과의 대소비교를 통해 탐색 범위를 줄여나가기 때문에 정렬되지 않은 배열에 사용하면 기대한 결과와 다르게 이상한 값이 반환된다.
public static void main(String[] args) {
int[] lottos = { 44, 1, 0, 0, 31, 25 };
int[] win_nums = { 31, 10, 45, 1, 6, 19 };
int match = 0;
Arrays.sort(lottos);
Arrays.sort(win_nums);
for(int lotto : lottos) {
if(Arrays.binarySearch(win_nums, lotto) >= 0) {
match++;
}
}
System.out.printf("번호가 %d개 일치합니다. %d등 당첨!", match, Math.min(7-match, 6));
}
번호가 2개 일치합니다. 5등 당첨!
3. anyMatch()
Arrays.stream(int[] array) 메서드를 사용하여 int 배열을 IntStream으로 변경한 뒤, .anyMatch() 메서드를 사용해 요소 중에서 key값과 일치하는 값이 존재하는지 여부(true/false)를 확인한다.
public static void main(String[] args) {
int[] lottos = { 44, 1, 0, 0, 31, 25 };
int[] win_nums = { 31, 10, 45, 1, 6, 19 };
int match = 0;
for(int lotto : lottos) {
if(Arrays.stream(win_nums).anyMatch(i -> i == lotto)) {
match++;
}
}
System.out.printf("번호가 %d개 일치합니다. %d등 당첨!", match, Math.min(7-match, 6));
}
번호가 2개 일치합니다. 5등 당첨!
4. contains()
Arrays.asList() 메서드를 사용하여 배열을 List로 변경한 뒤, contains() 메서드를 사용해 리스트 내 요소 중에 key값이 존재하는지 여부(true/false)를 확인한다.
public static void main(String[] args) {
Integer[] lottos = { 44, 1, 0, 0, 31, 25 };
Integer[] win_nums = { 31, 10, 45, 1, 6, 19 };
int match = 0;
for(Integer lotto : lottos) {
if(Arrays.asList(win_nums).contains(lotto)) {
match++;
}
}
System.out.printf("번호가 %d개 일치합니다. %d등 당첨!", match, Math.min(7-match, 6));
}
번호가 2개 일치합니다. 5등 당첨!
리스트화할 배열이 int[]타입이고 key값이 int타입일 경우 제대로 작동안할 수 있다. Arrays.asList()로 배열을 리스트화 할 때, List<T> asList(T...) 메서드의 제네릭스에 int[] 타입이 그대로 전달되어 List<int[]> 와 같이 int[]타입으로 리스트화되어 버리기 때문이다. (우리가 원한 건 List<int>) 그래서 int[] 배열을 asList(T..)로 리스트화한 다음 contains(int key)를 수행하게 되어버리면 '{ 1, 2, 3, 4 } == 3'과 같이 배열자체와 int값이 비교되어버려 무조건 false를 반환한다.
전달 인자 | asList() 기대 반환값 | asList() 실제 반환값 |
int[] array | List<int> | List<int[]> |
Integer[] array | List<Integer> | List<Integer> |
[참고]
- 2021 Dev-matching 웹 백엔드 개발 코딩테스트 문제
- Arrays.asList(int[]) not working, https://stackoverflow.com/a/31422046
'Algorithm' 카테고리의 다른 글
[BOJ] 백준 10951번 - A+B (0) | 2021.11.09 |
---|---|
[프로그래머스 / Level1] 실패율 (Java) (1) | 2021.11.08 |
[프로그래머스 / Level1] 숫자 문자열과 영단어 (Java) (0) | 2021.11.06 |
[프로그래머스 / Level1] 없는 숫자 더하기 (Java) (0) | 2021.11.05 |
[프로그래머스 / Level1] K번째 수 (Java) (0) | 2021.11.05 |