본문 바로가기

CS ﹒ Algorithm/Programmers

프로그래머스 문제풀이 (7) 신고 결과 받기

 

 

오늘도 카카오 문제다.

 

특정 알고리즘을 알아야만 풀 수 있는 문제가 아닌 기능 구현 문제이기 때문에 딱히 설명할 부분은 없다.

만약 도저히 방법을 모르겠다면 아래의 두 가지 사항을 고려해보자.

 

1. Stream API의 distinct() 메서드를 사용하면 중복된 값에 대한 연산을 제거할 수 있다. (난 이 방법으로는 풀지 않았다.)

2. Map을 어떻게든 잘 쓰면 솟아날 구멍은 있다.

 

 

첫 번째는 일단 부딪혀서 풀어봤고, 이후 다른 분이 클래스를 활용해서 문제를 푼 것을 보고 내 방식대로 클래스를 활용해서 한 번 더 풀어봤다.

당연히 두 번째가 훨씬 가독성도 좋고 조금 더 빠르다. (클래스가 들어가서 코드 자체는 더 길다.)

그래서 두 번째 답안을 먼저 올리겠다.

 

 

 

 

 

 

 

 

 

 

 

 

 

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
import java.util.*;
import java.io.*;
import java.util.stream.*;
 
class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
        Map<String, User> users = new HashMap<>(); // key : name, value : User
        int[] answer = new int[id_list.length];
        
        for ( int i=0; i<id_list.length; i++ ) {
            users.put(id_list[i],new User());
        }
        
        StringTokenizer st = null;
        for ( String str : report ) {
            st = new StringTokenizer(str, " ");
            
            String reporter = st.nextToken();
            String reported = st.nextToken();
            
           users.get(reported).BeReported(reporter); // 신고 당한 user의 Set에 신고자 추가
        }
        
        for ( String str : id_list ) {
            users.get(str).checkReportedCount(k, users);
       } // user 목록 돌면서 각 User의 신고 카운터 확인하고 기준치 이상이면 신고한 유저의 이메일카운터 +=1
        
        for ( int i=0; i<id_list.length; i++ ) {
            answer[i] = users.get(id_list[i]).getEmailCount();
       } // 유저 인덱스를 그대로 사용하기 때문에 그대로 결과 배열에 넣어서 반환
        
        return answer;
    }
    
    class User {
        private int emailCount;
        private Set<String> reportedRecord;
        
        public User () {
            this.emailCount = 0;
            this.reportedRecord = new HashSet<>();
        }
 
        public void incraseEmailCount() { // 이메일 수 증가
            this.emailCount += 1;
        }
        
        public int getEmailCount() { // 이메일 게터
            return this.emailCount;
        }
        
        public void BeReported(String userName) { // this를 리포트한 멤버 추가
            reportedRecord.add(userName);
        }
        
        public void checkReportedCount(int condition, Map<String,User> users) {
            if (reportedRecord.size() >= condition) {
                reportedRecord.stream()
                    .forEach(e-> users.get(e).incraseEmailCount());
            }
        }
    }
}
cs

 

 

다른 사람의 정답을 보고 영감을 얻어 작성하긴 했지만 그래도 이 정도면 나름 만족스럽다.

 

 

 

 

 

 

 

 

 

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
class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
        int[] answer = new int[id_list.length];
        Map<String, ArrayList<String>> result = new HashMap<>();
        Map<String, Integer> counter = new HashMap<>();
        StringTokenizer st;
 
        for ( String s : report ) {
            st = new StringTokenizer(s, " ");
 
            String reporter = st.nextToken();
            String reported = st.nextToken();
 
            if ( !result.containsKey(reporter) ) {
            result.put(reporter, new ArrayList<String>());
            }
 
            if ( !result.get(reporter).contains(reported) ) {
                result.get(reporter).add(reported);
                counter.put(reported, counter.getOrDefault(reported, 0+ 1);
            }
        }
 
        List<String> blackList = counter.keySet()
            .stream().filter( key -> counter.get(key) >= k)
            .collect(Collectors.toList());
 
            for (int i = 0; i < id_list.length; i++) {
                if (result.containsKey(id_list[i])) {
                    for ( String s : blackList) {
                        if (result.get(id_list[i]).contains(s)) {
                            answer[i]+=1;
                        }
                    }
                }
            }
 
        return answer;
    }
cs

 

이 방법도 마지막의 2중 (for - if)문만 아니면 그렇게 나쁘지는 않았던 것 같다.

저 부분만 조금 더 개선하면 빨라질 것 같은데

음.. 배고파서 그런지 머리가 잘 돌아가지 않는다고 핑계를 대며 마무리하겠다.

끝.