코딩테스트연습/프로그래머스

[프로그래머스 - JAVA] 실패율

:)jun 2021. 12. 3. 12:33

https://programmers.co.kr/learn/courses/30/lessons/42889

 

코딩테스트 연습 - 실패율

실패율 슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스

programmers.co.kr

// hashmap써서 key값에 stage명 넣고 value값에 사람 수 넣는다.
// key가 1인것부터 실패율을 구해주고 value 값을 기준으로 정렬한 다음 해당하는 key 배열을 구해준다.
// 이 정렬 과정에서 실패율이 같으면 낮은 stage명을 앞에 오게 해야하는데 정렬할때 이것까지 고려가 되려나..?
// 문제 풀기전에 value 값 기준 정렬, key 배열 구하는 것부터 연습해보자. 자주나오네

// 먼저 key를 정렬한 뒤 value 값 출력하는 방법
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class HashMapKeySorting {
    public static void main(String[] args) {

        Map<Integer, String> map = new HashMap<>(5);

        map.put(1, "apple");
        map.put(4, "pineapple");
        map.put(2, "orange");
        map.put(5, "strawberry");
        map.put(3, "melon");

        Object[] mapKey = map.keySet().toArray();
        Arrays.sort(mapKey);

        for(Object nKey : map.keySet()){
            System.out.println(map.get(nKey));
        }
    }
}
// key는 하나씩 뿐이니까 정렬한 뒤에 여기에 맞는 value 값을 get으로 찾아주면 되겠다!

// 이젠 value 값을 정렬한뒤 key값을 찾아보자.
import java.util.*;
import java.util.Comparator;

public class HashMapValueSorting {
    public static void main(String[] args) {

        Map<String, Integer> map = new HashMap<>(5);

        map.put("apple", 1);
        map.put("orange", 2);
        map.put("pineapple", 4);
        map.put("strawberry", 5);
        map.put("melon", 3);

        List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());

        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return o1.getValue() - o2.getValue();
            }
        });

        for (Map.Entry<String, Integer> entry : list) {
            System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
        }
    }
}

// ArrayList에서 Entry객체를 다 넣어주고 이 list를 각각의 Entry.getvalue()기준으로 Collections.sort 해줬다.
// 정렬된 list를 Entry.getkey()로 뽑아주면 끝!
// 혹시 List가 아니라 Array에 담아줘도 가능할까?

import java.util.*;
import java.util.Comparator;

public class HashMapValueSorting {
    public static void main(String[] args) {

        Map<String, Integer> map = new HashMap<>(5);

        map.put("apple", 1);
        map.put("orange", 2);
        map.put("pineapple", 4);
        map.put("strawberry", 5);
        map.put("melon", 3);

        Map.Entry<String,Integer>[] arr = map.entrySet().toArray(new Map.Entry[0]);



        Arrays.sort(arr, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return o1.getValue() - o2.getValue();
            }
        });

        for (Map.Entry<String, Integer> entry : arr) {
            System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
        }
    }
}

// 물론 된다!! map.entrySet().toArray 로 배열로 바꿔주고 new Map.Entry[0]으로 캐스팅 해준것을 유심히 봐라! 어제 했던것!
// 이제 다시 문제로 돌아와서 사용해보자!

//테스트코드
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class Quiz1_falseRateTest {

    Quiz1_falseRate q;

    @BeforeEach
    void setUp() {
        q = new Quiz1_falseRate();
    }

    @Test
    void 스테이지1_스테이지스1일경우() {
        assertArrayEquals(new int[]{0}, q.solution(1, new int[]{2}));
    }

    @Test
    void test2() {
        assertArrayEquals(new int[]{3, 4, 2, 1, 5}, q.solution(5, new int[]{2, 1, 2, 6, 2, 4, 3, 3}));
    }

    @Test
    void test3() {
        assertArrayEquals(new int[]{4, 1, 2, 3}, q.solution(4, new int[]{4, 4, 4, 4, 4}));
    }
}

//프로덕션코드
import java.util.*;
import java.util.Comparator;

public class Quiz1_falseRate {
    public int[] solution(int N, int[] stages) {

        Map<Integer, Integer> map = new HashMap<>(N + 1);
        for (int i = 1; i <= N + 1; i++) {
            map.put(i, 0);
        }

        for (int i = 0; i < stages.length; i++) {
            int newValue = map.get(stages[i]) + 1;
            map.put(stages[i], newValue);
        }


        Map<Integer, Double> falseRateMap = new HashMap<>(N);

        for (int i = 1; i <= N; i++) {
            falseRateMap.put(i, getFalseRate(i, N, map));
        }

        List<Map.Entry<Integer, Double>> list = new ArrayList(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<Integer, Double>>() {
            @Override
            public int compare(Map.Entry<Integer, Double> o1, Map.Entry<Integer, Double> o2) {
                if (o1.getValue() > o2.getValue()) return -1;
                if (o1.getValue() < o2.getValue()) return 1;
                return 0;
            }
        });

        int[] answer = new int[N];

        int i = 0;
        for (Map.Entry element : list) {
            answer[i] = (int) element.getKey();
            i++;
        }
        return answer;

    }

    double getFalseRate(int i, int N, Map<Integer, Integer> map) {
        int totalNumberOfPeopleReached = 0;
        for (int j = i; j <= N + 1; j++) {
            totalNumberOfPeopleReached += map.get(j);
        }
        return map.get(i) / (double) totalNumberOfPeopleReached;
    }
}

// java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Double (java.lang.Integer and java.lang.Double are in module java.base of loader 'bootstrap')
// return 값도 정수로 맞춰줬는데 왜 안될까?
// return Double.compare(o1.getValue(), o2.getValue()) 해줘도 안되네..

// 공부하고 다시 오겠습니다.