알고리즘/프로그래머스 Level2

[프로그래머스,Java] Levle2: 메뉴 리뉴얼

류창 2021. 10. 17. 23:21
반응형

문제분석

여러모로 할게 많은문제다..

 

1. 각 손님들이 주문한 메뉴들을 기준으로, n개의 메뉴조합을 만든다.

 

2. 모든 메뉴조합의 카운트를 세준다. 2회 이상 나온것만 메뉴후보로 친다.

 

3.메뉴 후보를 정했다면, 가장 많이나온 메뉴후보를 선정한다.

 

4.만약, 가장 많이 나온 메뉴후보가 여럿있다면, 모두 출력하라.

 

 

 

필자의 문제 접근

 

우선, 순수한 단품메뉴들을 모아보고싶었다. 순수한 단품메뉴들의 모든 N개의 조합을

List로 넣어, 모든 조합을 정해놓고 손님들에게 넣어보며 카운트를 세주고싶었다.

 

1.Set<> 배열로,모든 손님의 단품메뉴들을 모아보았다.

 

2.단품메뉴들을 토대로, course[]의 숫자에따라 조합알고리즘을 적용한다.

 

모든 조합은 List<> case로 저장을했다.

 

3.cases에 들어있는 메뉴들의 조합을 순회하며, 

각 손님들이 메뉴조합을 주문했는지 count를 세준다. 

 

4.count가 2 이상이면,  메뉴후보에 넣는다.

// 넣을때, ( cnt, 메뉴) 배열형식으로 넣자. 나중에 cnt로 지정정렬 해야한다.

 

5.메뉴후보를 정했다면,  cnt를 기준으로 지정정렬한다.

 

만약, 가장 많은 메뉴 후보가 여럿있으면 모두 출력한다.

 

문제풀이

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import java.util.*;
class Solution {
    static List<String> cases = new ArrayList<>();
    
    public List<String> solution(String[] orders, int[] course) {
        List<String> answer = new ArrayList<>();
        //Set 으로 단품메뉴가 뭐가있는지 메뉴를 넣고 중복제거
        Set<String> set = new HashSet<>();
        for(String data:orders){
            String[] orders_sp=data.split("");
            for(String data2:orders_sp){
                set.add(data2);
            }
        }
        String[] Smenu = new String[set.size()];
        set.toArray(Smenu);
        boolean[] visited = new boolean [Smenu.length];    
        for(int num:course){
       
        cases.clear();
       
        List<String[]> count =new ArrayList<>();     
        comb(Smenu,visited,0,num);
        // 손님들이 코스 cases를 2명 이상이 주문햇는지 확인 
        
        for(int i=0;i<cases.size();i++){
            int cnt=0;
            for(int j=0;j<orders.length;j++){
                String[] temp=cases.get(i).split("");
                boolean flag = true;
                if(cases.get(i).length()>orders[j].length()){
                   continue;
                }
                for(String data:temp){
                    if(orders[j].contains(data)){
                        flag=true;
                    }
                    else{
                        flag=false;
                        break;
                    }
                }
                if(flag==true){
                    cnt++;
                }
            }
            if(cnt>=2){
                count.add(new String[]{cnt+"",cases.get(i)});
            }
        }
        // count가 없으면 생략, 있다면 제일 인기많은 후보 출력
        if(count.isEmpty()){
            break;
        }
        else{
        Collections.sort(count,(a,b)->Integer.parseInt(b[0])-Integer.parseInt(a[0]));
        
        //만약 Max주문횟수가 여러개있음을 가정하여 주문후보 출력
        String maxcount=count.get(0)[0];
        for(String[] data:count){
            if(maxcount.equals(data[0])){
                answer.add(data[1]);
            }
        } 
        }
        }     
        //사전순정렬
        Collections.sort(answer);
        
        return answer;
    }
    
    // 조합
    static public void comb (String[] Smenu,boolean[] visited,int start,int r){
        if(r == 0) {
            print(Smenu,visited);
            return;
        } 
        else {
            for(int i = start; i < Smenu.length; i++) {
                visited[i] = true;
                comb(Smenu, visited,i + 1, r - 1);
                visited[i] = false;
            }
        }
    }
    //출력 함수: 손님들이 주문한메뉴로 가능한 조합을 모두넣음
    static void print(String[] Smenu, boolean[] visited) {
        String temp="";
        for(int i = 0; i < Smenu.length; i++) {
            if(visited[i] == true){
                temp+=Smenu[i];
            }
        }
        cases.add(temp);
    }
}
cs
반응형