https://school.programmers.co.kr/learn/courses/30/lessons/42889
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
실패율 문제.
초기 작성코드 우선 올리도록 함.
import java.text.CollationKey;
import java.util.*;
import java.util.stream.Collectors;
class Solution {
public int[] solution(int N, int[] stages) {
int[] answer = new int[N];
// 배열 users 선언. 길이는 N / 전체 유저수 선언 stages.length
int[] users = new int[N];
int remainUsers = stages.length;
// 초기값 0으로 배열 채우기
Arrays.fill(users, 0);
// stages 를 순회하면서 각 머물고 있는 스테이지를 확인 후 각 위치(스테이지 -1 = 인덱션)에 숫자 넣기.
// 이미 0으로 다 채워두어서 향상된 for문 가능.
for (int c : stages) {
users[stages[c] - 1]++;
}
// 새로운 맵 선언 (실패율)
Map<Integer, Double> failure = new HashMap<>();
// 각 users / 전체 유저수 로 실패율 조사.
// 1스테이지부터 진행해서 진행할수록 전체 유저수 차감
// double 맵에 해당 스테이지(키)에 밸류로 담기
// 남은 유저가 없다면 (분모가 0이되면) 키값은 입력, 밸류는 0
for (int i = 0; i < users.length; i++) {
if(remainUsers > 0) {
failure.put(i + 1, (double) users[i] / remainUsers);
remainUsers -= users[i];
} else {
failure.put(i, 0.0);
}
}
// value 를 정렬하여 리스트에 담기위해 배열을 생성하고 리스트에 담는다.
double[] failureArray = new double[failure.size()];
Arrays.sort(failureArray);
List<Double> failureList = new ArrayList<>();
for (int i = 0; i < failureArray.length; i++) {
failureList.add(failureArray[i]);
}
// 리스트를 순회하면서 Map 에 해당 밸류의 키값을 answer 배열에 차례로 입력.
for (int i = 0; i < failureList.size(); i++) {
failureArray[i] = failure.remove(failureList.get(i));
}
for (int i = 0; i < failureArray.length; i++) {
answer[i] = (int) failureArray[i];
}
return answer;
}
}
문제발생 이유 및 파악
기존에 구글링 해서 풀었던 문제를 다시 풀면서 구글링없이 푸는 방법을 모색하려고 재도전.
구글링을 통해서 Map의 value 정렬을 하면 쉽게 풀 수 있는 문제였지만, 해당 방법이 내가 다시 풀 때 전혀 사용하지 못할 방법이라고 판단하여 다시 새롭게 풀려고 하였다.
하지만 역시나 난관에 부딪혔다.
늘 나를 맞이하는 ArrayIndexOutOfBoundsException...
분명 어느정도 코드는 내 생각에 맞게 작성하였다고 생각하였으니 또다시 Array index 관련 에러를 만났다.
늘 만나는 문제라 이제 어느정도는 익숙해졌다 싶었는데도 이번에는 쉽사리 해결방법을 찾지 못하였다.
예측되는 문제점은 n+1 이 들어오는 점에 대응하지 않는 부분?
하지만 이 부분은 반복문을 순회하면서 해당 부분에 대한 대응이 없더라도 실패율 조사에는 이상이 없는 코드라 생각한다.
해결방법 도색
1. stages를 순회하면서 users 배열에 ++ 해주는 부분에서 향상된 for 문을 사용하며 그 부분에서 오류가 발생했을 가능성
2. failure (Map)에 키값과 밸류값을 입력할 때 if 부분에는 i + 1 인데 else 부분에 i + 1 이 아닌 점에서 오류가 발생했을 가능성
해결방법 진행 후
ArrayIndexOutOfBoundsException 이 사라졌다!
근데 바로 NullPointException 으로 변했다.....
수정코드. 몇차례 수정인지도 모르겠다.
일단 NullPointException은 사라지고 답이 도출은 되는데 영 이상한 값이 나온다. 이 부분은 추후 재 수정해보자.
import java.util.*;
class Solution {
public int[] solution(int N, int[] stages) {
int[] answer = new int[N];
// 배열 users 선언. 길이는 N + 1 / 전체 유저수 선언 stages.length
int[] users = new int[N + 2];
int remainUsers = stages.length;
// 초기값 0으로 배열 채우기
Arrays.fill(users, 0);
// stages 를 순회하면서 각 머물고 있는 스테이지를 확인 후 각 위치에 숫자 넣기.
for (int i = 0; i < stages.length; i++) {
users[stages[i]]++;
}
// 새로운 맵 선언 (실패율)
Map<Integer, Double> failure = new HashMap<>();
// 각 users / 전체 유저수 로 실패율 조사.
// 1스테이지부터 진행해서 진행할수록 전체 유저수 차감
// double 맵에 해당 스테이지(키)에 밸류로 담기
// 남은 유저가 없다면 (분모가 0이되면) 키값은 입력, 밸류는 0
for (int i = 0; i < N; i++) {
if(remainUsers > 0) {
failure.put(i + 1, (double) users[i] / remainUsers);
remainUsers -= users[i];
} else {
failure.put(i + 1, 0.0);
}
}
// 배열을 만들어 초기값 0.0을 담아준 후 value 를 배열에 담고 정렬한다.
double[] failureArray = new double[N];
Arrays.fill(failureArray, 0.0);
for (int i = 0; i < N; i++) {
failureArray[i] = failure.get(i + 1);
}
Arrays.sort(failureArray);
// 리스트를 순회하면서 Map 에 해당 밸류의 키값을 answer 배열에 차례로 입력.
for (int i = failureArray.length - 1; i >= 0; i--) {
for (int j = 1; j <= N; j++) {
if (failure.get(j) != null) {
if (failure.get(j).equals(failureArray[i])) {
answer[i] = j;
failure.remove(j);
}
}
}
}
return answer;
}
}'코딩공부' 카테고리의 다른 글
| 트러블슈팅 - Post Ban 오류 (0) | 2024.10.08 |
|---|---|
| 2차 프로젝트(EVision) 트러블슈팅 (0) | 2024.09.23 |
| 240725 코딩테스트 난관(StringIndexOutOfBoundsException) (0) | 2024.07.25 |
| 240723 JPA 시작 오류 (0) | 2024.07.24 |
| 240723 코딩테스트 오류(초기값 설정 - 최소값/최대값) (4) | 2024.07.23 |