신고 결과 받기 with cpp & c#
태그: BOJ, C#, C++, kakao, programmers
카테고리: CodingTest
프로그래머스 신고 결과 받기 with c++ & c#
문제 링크 신고 결과 받기
이 문제를 풀면서 정말 많은 것을 배운 것 같다.
C++
unordered_map
과 unordered_set
을 사용해보자.
unordered_map : 중복을 허용하지 않고 , 정렬없이 저장한다.
1
hash_map 은 unordered_map 과 굉장히 유사하지만 성능에서 밀리기 때문에 권장되지 않음.
unordered_set : 중복을 허용하지 않고 , 정렬없이 저장한다.
1
원소가 많으면 hash 충돌이 발생하기 때문에 원소의 개수가 적고 빠른 성능을 원할 때 사용.
Key 와 Value 쌍으로 이루어진 경우는 map, Key 그 자체가 데이터라면 set 이라고 한다.
둘 다 중복된 키 값은 알아서 무시한다.
문제
문제를 읽어보면 한 유저가 여러 번 신고할 수는 있지만, 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;
}
}
댓글남기기