개?발/프로그래머스

데이터 분석(Java)

YUEIC 2024. 5. 27. 16:29

코드번호, 제조일, 최대수량, 현재 수량 으로 이루어진 1차원 배열을 여러개 이은 2차원배열이 주어지면

1 기준이 되는 요소에 대한 일정 수치 이하인 배열만

2 기준이 되는 요소가 오름차순이 되도록 배열을 출력하는 문제이다.

 

 public int[][] solution(int[][] data, String ext, int val_ext, String sort_by) {
        int[][] answer;
        int crit = 0;       //제한 기준

        ArrayList<int[]> dataList = new ArrayList<>(); //데이터를 담을 리스트

        for(int i = 0 ; i < data.length; i ++){         //데이터배열을 리스트화
            dataList.add(data[i]);
        }

        switch (ext) {
            case "code":
                crit = 0;
            break;
            case "date":
                crit = 1;
            break;
            case "maximum":
                crit = 2;
            break;
            case "remain":
                crit = 3;
            break;
            default:
                break;
        }

        for(int i = 0 ; i < dataList.size() ; i++){
            if(dataList.get(i)[crit] > val_ext){
                dataList.remove(i);
                i -= 2;
            }

        }

        switch (sort_by) {
            case "code":
            dataList.sort(Comparator.comparing(o -> o[0]));
            break;
            case "date":
            dataList.sort(Comparator.comparing(o -> o[1]));
            break;
            case "maximum":
            dataList.sort(Comparator.comparing(o -> o[2]));
            break;
            case "remain":
            dataList.sort(Comparator.comparing(o -> o[3]));
            break;
            default:
                break;
        }

        
        

        answer = new int[dataList.size()][4];
        for(int i = 0 ; i< dataList.size() ; i++){
            answer[i] = dataList.get(i);
        }

        // for(int i = 0 ; i < answer.length; i++){
        //     System.out.print(answer[i][0] + ", ");
        //     System.out.print(answer[i][1] + ", ");
        //     System.out.print(answer[i][2] + ", ");
        //     System.out.println(answer[i][3]);
        // }
        return answer;
    }

나는 먼저 정렬을 쉽게 하기 위해 배열을 리스트로 변경했다.

그리고 1 기준이 될 변수의 string 값을 switch문으로 판별했고 2 기준이 될 변수도 switch문으로 판별했다.

그리고 1기준보다 큰 요소를 리스트에서 제거했고 2기준 요소를 오름차순 정렬해서 반환했다

 

그랬더니 몇개는 맞고 몇개는 틀린다...

런타임 오류가 나는데 어디가 문제인지 알 수 없어 고민하다 다른 방법을 검색해보았다.

    public int[][] solution(int[][] data, String ext, int val_ext, String sort_by) {
        int[][] answer;

        Map<String, Integer> colOrder = new HashMap<>();
        colOrder.put("code", 0);
        colOrder.put("date", 1);
        colOrder.put("maximum", 2);
        colOrder.put("remain", 3);
        
        int[][] filteredData = Arrays.stream(data).filter(x -> x[colOrder.get(ext)] < val_ext).toArray(int[][]::new);
        Arrays.sort(filteredData, (o1, o2) ->  o1[colOrder.get(sort_by)] - o2[colOrder.get(sort_by)]);

        answer = filteredData;
        
        return answer;
    }

 

이 분이 쓰신 방법은 

switch -> hashMap

리스트 -> 배열stream

이었다.

 

처음에는 코드 이해를 잘못해서 data 이차원 배열을 hashMap으로 변경한 줄 알았는데 기준1, 기준2 값을 변경한 것이었다.

stream도 람다식도 배경지식이 없어서 하루종일 그것만 찾아봤다.(그래도 완벽히 이해는 안됐다...) 그리고 내가 작성했던 코드에 끼워맞추기 식으로 적용했다.

class Solution {
    int crit = 0;
    int crit2 = 0;
    
    public int[][] solution(int[][] data, String ext, int val_ext, String sort_by) {
        int[][] answer;


        int[][] filteredData = {};
        Stream<int[]> dataStream = Arrays.stream(data);

        switch (ext) {
            case "code":
                crit = 0;
            break;
            case "date":
                crit = 1;
            break;
            case "maximum":
                crit = 2;
            break;
            case "remain":
                crit = 3;
            break;
            default:
                break;
        }
        switch (sort_by) {
            case "code":
                crit2 = 0;
            break;
            case "date":
                crit2 = 1;
            break;
            case "maximum":
                crit2 = 2;
            break;
            case "remain":
                crit2 = 3;
            break;
            default:
                break;
        }

        filteredData = dataStream.filter( x -> x[crit] < val_ext).toArray(int[][]::new);

        Arrays.sort(filteredData, (o1, o2) -> o1[crit2] - o2[crit2]);

        answer = filteredData;

        return answer;
    }
}

그렇게 나온게 이것

 

switch문으로 기준1 기준2를 선별하는 방법은 굳이 건드리지 않았다.

변경된 점은 data 이차원 배열을 순회하는 dataStream을 생성하고 기준1이 적용된 이차원 배열이 담길 filteredData를 생성했다.

이때 filteredData로 기준1을 적용할 때 위에서 생성한 dataStream을 사용했는데 람다식 안에 crit이란 변수를 사용할 때 문제가 발생했었다.

crit변수를 solution 메서드 안에 선언했던게 문제였다. 람다식 안에서는 변수가 변경될 수 없기때문이라고 한다. 해결방법은 변수를 class단에 선언하는 것. 그래서 crit, crit2 변수를 solution 메서드 밖에 선언했다.

이후 기준1이 적용된 filteredData배열을 기준2 요소가 오름차순이 되도록 sort하여 제출했다.

결과는 통과

 

이게 왜 4점밖에 안되는 문제인지 잘 모르겠다...

'개?발 > 프로그래머스' 카테고리의 다른 글

대충 만든 자판(java)  (0) 2024.05.30
덧칠하기(java)  (0) 2024.05.27
이웃한 칸(java)  (0) 2024.05.21
붕대감기 (java)  (0) 2024.05.21
요격 시스템 (C#)  (0) 2024.05.13