프로그래머스 코딩테스트 연습 - 실패율

김영신·2022년 4월 14일
0
post-thumbnail

나는 이런 방식으로 풀었다.
일단 stages의 원소들을 정렬하여 인덱스 0 부터 반복을 돌려서 다음 원소가 N이 아닐때 까지
count는 1씩 증가하고
N이 아닌 경우 count와 stages의 크기를 나눠 실패율을 구했다.

import java.util.*;
import java.util.stream.*;

class Solution {
    public int[] solution(int N, int[] stages) {
        // 배열을 리스트에 담아서 정렬
        List<Integer> arr = new ArrayList<Integer>();
        Arrays.stream(stages).forEach(arr::add);
        Collections.sort(arr);

배열을 리스트에 담아서 subList(beginIndex, lessEndIndex)를 사용하기 위함이다.

        // key는 스테이지, value는 실패율
        var answerMap = new HashMap<Integer, Double>();

스테이지 마다의 실패율을 담을 맵을 생성한다.

        // 스테이지마다 각각 실패율 계산후 리스트 추출
        for (int stage = 1; stage <= N; stage++) {
            int size = arr.size(); 리스트 혹은 분할된 리스트의 크기
            int count = 0; 성공한 사람들의 수
            while(true){
            	<쇼트서킷을 주의하여 코드 작성>
                if(count == arr.size() || arr.get(count) != stage) break;
                count++;
            }
            double value = 1- (count / (double)size);
            answerMap.put(stage, value);
            if(count != 0){
                arr = arr.subList(count, size);
            }
        }

그리고 double value = 1 - (count / (double) size); 이 부분 원래는...
그냥 실패율만으로 하면 에러가 자꾸나서 혹시나 해서 성공율로 해보았는데 되었다.
뭔 차이 일까...

무튼 해당 반복을 돌면서 만약 arr에 size가 0이라면 우선적으로 실패율 과정으로 넘어가고
arr의 count의 원소가 N이 아니라면 실패율 구하는 과정으로 넘어간다.

아까 위에서 우리는 성공자들을 다 정렬해주었다.

실패율을 구한 뒤 해당 스테이지를 못 끝낸 인원을 제외한 새로운 스테이지 도전자 arr 리스트를 생성한다.
왠만하면 자바의 대부분의 메서드들은 보통 start 이상, end 미만이라고 생각하자.
subList(start, end)


쇼트서킷이란?

AND나 OR의 연산에서 하나의 부호가 리턴되는 결과에 영향을 미칠 경우 나머지의 연산을 하지 않고
결과를 출력하는 것을 말한다.

AND 같은 경우는 2개의 부호가 true 여야지만 true를 리턴한다고 하였다.
앞에서 하나의 부호가 false가 나와버리면 뒤의 연산을 하지도 않고 결과를 리턴한다.

마찬가지로 OR 같은 경우는 앞에서 하나의 부호가 true가 나와버리면 뒤의 연산을 하지도 않고
결과를 리턴할 것이다.

ex )

int a = 1;
int b = 2;
boolean test = a > b;  // false
System.out.println( test && (a++ == 1) ); // a++ 연산이 진행되지 않음
System.out.println(a); // 1

System.out.println( true || (a++ == 1) ); // 마찬가지로 a++ 연산이 진행되지 않음
System.out.println(a); // 1


        // 맵을 entry 쌍으로 만들어 stream을 통한 내림차순 Entry의 value정렬을 한뒤 그것을 리스트로 반환
        var entries = answerMap.entrySet().stream()
        .sorted(Map.Entry.comparingByValue()).collect(Collectors.toList());
}

이제 맵 안에 있는 키들을 1 2 3 4 순서대로 있을 것이다.
value값의 크기에 따라 분류를 하면 되고 같은 값이 있더라도 이미 키는 순차적으로 나열되 있기 때문에 문제의 조건에 맞다.

var는 지역 변수에 한해서 쓸 수 있는 키워드로 길고 긴 타입명 지정을 생략할 수 있다.
var entries를 타입명으로 다시 바꿔쓰면..
List<Map.Entry<Integer, Double>> entries 가 된다.

answerMap.entrySet()으로 Set형식으로 키와 값들 쌍으로 만들고 그 값들을 stream().sorted(Map.Entry.comparingByValue()) 을 통하여 Entry의 value에 따라 오름차순으로 분류하고 ( 아까전에 성공률로 계산했다. )
collect(Collectors.toList())그 분류한 값들을 List로 받았다.

        var answer = new int[entries.size()];
        int index = 0;
        for(var entry : entries){
            answer[index++] = entry.getKey();
        }
        return answer;
    }

이제 정답을 담을 배열을 entries의 크기만큼 (entries는 list이다) 생성해주고
해당 리스트에 있는 Entry에 getKey() 메서드를 사용하여 키를 구한다.
그리고 그것을 정답 배열에 담아주고 리턴하면 이 문제는 끝이다.

import java.util.*;
import java.util.stream.*;
class Solution {
    public int[] solution(int N, int[] stages) {
        // 배열을 리스트에 담아서 정렬
        List<Integer> arr = new ArrayList<Integer>();
        Arrays.stream(stages).forEach(arr::add);
        Collections.sort(arr);

        // key는 스테이지, value는 실패율
        var answerMap = new HashMap<Integer, Double>();

        // 스테이지마다 각각 실패율 계산후 리스트 추출
        for (int stage = 1; stage <= N; stage++) {
            int size = arr.size();
            int count = 0;
            while(true){
            	// 쇼트서킷을 주의하여 코드 작성
                if(count == arr.size() || arr.get(count) != stage) break; 
                count++;
            }
            double value = 1- (count / (double)size);
            answerMap.put(stage, value);
            if(count != 0){
                arr = arr.subList(count, size);
            }
        }
        
        // 맵을 entry 쌍으로 만들어 stream을 통한 내림차순 Entry의 value정렬을 한뒤 그것을 리스트로 반환
        var entries = answerMap.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toList());
        var answer = new int[entries.size()];
        int index = 0;
        for(var entry : entries){
            answer[index++] = entry.getKey();
        }
        return answer;
    }
}
profile
어제보다 오늘 더 Developer

0개의 댓글