Publish:

태그: , , , ,

카테고리:

프로그래머스 신고 결과 받기 with c++ & c#

문제 링크 신고 결과 받기

이 문제를 풀면서 정말 많은 것을 배운 것 같다.

C++

unordered_mapunordered_set 을 사용해보자.

unordered_map : 중복을 허용하지 않고 , 정렬없이 저장한다.

1
hash_map 은 unordered_map 과 굉장히 유사하지만 성능에서 밀리기 때문에 권장되지 않음.

unordered_set : 중복을 허용하지 않고 , 정렬없이 저장한다.

1
원소가 많으면 hash 충돌이 발생하기 때문에 원소의 개수가 적고 빠른 성능을 원할 때 사용.

Key 와 Value 쌍으로 이루어진 경우는 map, Key 그 자체가 데이터라면 set 이라고 한다.

1

둘 다 중복된 키 값은 알아서 무시한다.

문제

문제를 읽어보면 한 유저가 여러 번 신고할 수는 있지만, 1회로 처리한다. 라는 문구가 있다.

이는 중복을 허용하지 않는다는 뜻이므로 위의 map 과 set 을 사용한다.

코드

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
#include <string>
#include <vector>
#include <unordered_map> // 정렬 x
#include <unordered_set>

using namespace std;

// id_list : 유저 리스트 , report : 신고 현황 , k : 체크할 정지 횟수
vector<int> solution(vector<string> id_list, vector<string> report, int k) {
    unordered_map<string, unordered_set<string>> reportHash; // Key : 신고한 사람
    unordered_map<string, unordered_set<string>> resultHash; // Key : 신고 받은 사람
    
    // report 에서 문자열을 신고한 사람과 신고받은 사람으로 분리
    for(string r : report) 
    {
        int pos = r.find(' ');
        string user = r.substr(0, pos);
        string bad = r.substr(pos + 1);
        reportHash[user].insert(bad);
        resultHash[bad].insert(user);
    }
    
    vector<int> answer(id_list.size());
    for(int i = 0; i < id_list.size(); ++i)
    {
        string user = id_list[i];
        auto it = reportHash.find(user); // user 가 신고한 사람이 있는지 확인
        if(it == reportHash.end()) continue; // 없으면 continue
        
        for(string bad : it->second) // 있으면 resultHash 체크
        {
            if(resultHash[bad].size() >= k) // 신고한 사람이 k 명 이상인 경우
            {
                ++answer[i];
            }
        }
    }
    return answer;
}

C#

비교

내가 Unity 를 공부하며 익힌 언어가 C# 이기 때문에 C# 으로 풀어보고 싶다고 생각하였다.

그래서 도전해보았다.

C++ 에 unordered_map 이 있다면 C# 에는 Dictionary 가 있다.

C++ 에 unordered_set 이 있다면 C# 에는 HashSet 이 있다.

언어적인 측면에서 다른 점이 있다.

C++ 은 reportHash 에 Key 가 있든 없든 그냥 reportHash[user].insert(bad); 로 넣어보면 된다.

있으면 덮어쓸거고 없으면 데이터가 들어간다.

하지만 C# 은 그렇지가 않다.

만약 중복된 값이 있다면 오류가 뜬다.

그래서 조건문으로 검사해주어야 한다.

코드

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
using System;
using System.Collections.Generic;

public class Solution {
    public int[] solution(string[] id_list, string[] report, int k) {
        int[] answer = new int[id_list.Length];
        Dictionary<string, HashSet<string>> reportDic = new Dictionary<string, HashSet<string>>();
        Dictionary<string, HashSet<string>> resultDic = new Dictionary<string, HashSet<string>>();
        
        foreach(var str in report)
        {
            int index = str.IndexOf(' ');
            string user = str.Substring(0, index);
            string bad = str.Substring(index + 1);
            
            if(reportDic.ContainsKey(user) == false)
                reportDic.Add(user, new HashSet<string>());
            if(resultDic.ContainsKey(bad) == false)
                resultDic.Add(bad, new HashSet<string>());
            reportDic[user].Add(bad);
            resultDic[bad].Add(user);
        }
        
        for(int i = 0; i < id_list.Length; ++i)
        {
            string user = id_list[i];
            if(reportDic.ContainsKey(user) == false) continue;
            
            foreach(var bad in reportDic[user])
            {
                if(resultDic[bad].Count >= k)
                {
                    ++answer[i];
                }
            }
        }
        return answer;
    }
}
방문해 주셔서 감사합니다!😊

업데이트:

댓글남기기