[JAVA] 음수를 포함한 영역의 최빈값을 계산하기
※ 본 포스팅은 프로그래머스에 있는 연습문제 풀었던 내역을 아카이빙하기 위해 작성했습니다.
작성자의 공부를 목적으로 작성된 포스팅입니다.
이 포스팅은 방법을 제시한다기보다 제가 어떤 어려움을 겪었는지를 기록하는 목적으로 작성되었습니다.
혹시나 더 좋은 솔루션이 있으실 경우 태클도 환영입니다!!
주어진 array 라는 배열이 있고
그 배열의 길이는 0과 100 사이이며
array의 원소는 절대값 1000 이하일 때
음수가 최빈값으로 올 경우에 대비해서 처음에는
각 숫자를 카운팅하기 위해 배열을 선언할 때 단순하게 1000을 더했었다.
int max = 0;
int answer = 0;
int [] count = new int[array.length+1001];
이런 식으로
0을 처리하기 위해서
또 6번째 배열은 index[5]로 표시해야하기 때문에 1을 더해주고 음수 영역이라고 생각했던 1000을 더해서 array.length+1001이라고 코드를 짰었다.
작은 숫자일 때는 문제가 없었으나... 문제는
int[] array = {1, -3, -3, -3, -4, -4, -4,5,5,5,6,7,8,9,10,
999,999,999,999,-999,-999,-999,-999,-999};
이런 상황일 때 나타났다.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 1999 out of bounds for length 1025
이 에러문구를 보고 나서 무릎을 탁 쳐버렸다.
처음엔 안일하게 음수를 넣기 위해서 음수가 나올 수 있는 영역인 1000만 더했는데,
이렇게 해버리면 array.length+1001는 끽해봐야 1000에서 크게 벗어나지 못하는 수준이라 받아들일 수 있는 수의 범위가 한정되어 있다.
결국 -1000 < array의 원소 < 1000을 표현하려면
카운트를 할 변수를 2001개만큼 인덱스를 선언해줘야했다.(양수 1000, 음수1000, 0을 처리할 1자리)
그래서 이렇게 코드를 짜보니 에러 없이 잘 실행이 되었다.
public static void main(String[] args) {
// 최빈값은 주어진 값 중에서 가장 자주 나오는 값을 의미합니다.
// 정수 배열 array가 매개변수로 주어질 때, 최빈값을 return 하도록 solution 함수를 완성해보세요.
// 최빈값이 여러 개면 -1을 return 합니다.
int[] array = {1, -3, -3, -3, -4, -4, -4,5,5,5,6,7,8,9,10,
999,999,999,999,-999,-999,-999,-999,-999};
// 최빈값을 받을 변수 선언 및 초기화
int answer = 0;
int [] count = new int[2001];
answer = mode(array, count);
System.out.println(answer);
}
private static int mode(int[] array, int[] count) {
int max = 0;
int answer = 0;
for(int i = 0;i<array.length;i++) { // array.length의 길이만큼 돌아갈 for문
// 배열에 들어가 있는 값이 양수일 경우 처리할 구문
if(array[i]>0){
count[array[i]]++;
}
// 배열에 들어가 있는 값이 음수일 경우 처리할 구문
else if(array[i]<0){
count[(array[i]*(-1))+1000]++;
}else{
array[0]++; // 배열의들어가 있는 값이 0일 경우 처리할 구문
}
}
for( int i=0; i<count.length; i++) {
// array배열과 count 배열을 한번에 합쳐서 생각했더니
// 코드가 너무 꼬여서 for문을 두번 사용하였다.
// 애초에 윗 단계에서 count에 값을 다 쌓은 후에 써야했다.
// for문을 돌면서 count 각 항에 쌓인 값이 가장 높은 항을 찾는다.
if(count[i] > max) {
max = count[i]; // 최대값은 따로 저장을 해두고
answer = i; // 그 최대값이 있던 항의 인덱스 번호가 원래 array에 있던 숫자다.
}
for(int j=i+1; j<count.length; j++) {// 최빈값이 2개라면 -1을 리턴하는 구문
if(count[i]==max && count[j]==max) {
answer = -1;
}
}
}
// 위에서 음수일 때 인덱스번호를 1000을 더했기 때문에 데이터원복
if(answer > 1000){
answer = (answer - 1000)*(-1);
}
return answer;
}