티스토리 뷰

본 포스팅은 '신고 결과 받기' 문제에 대해 여준 님께서 작성하신 코드에서 배운 내용을 정리했습니다.

 

[프로그래머스] 신고 결과 받기 풀이 (2022 카카오 코딩테스트)

프로그래머스 - 신고 결과 받기 C++ 풀이 (2022 카카오 블라인드 채용 1차 코딩테스트)

yjyoon-dev.github.io

 

 

1. map::find()

map 컨테이너는 key와 value의 쌍으로 이루어진 '트리'이다. map에서 원하는 key 값을 찾기 위해서는 find() 메서드를 사용한다. 

  반환값
찾은 경우 iterator
못 찾은 경우 map::end

+ iterator가 아닌 그냥 조사만 하는 경우라면 std::count()를 쓰는 것을 추천한다. 원래 count()는 원소가 몇 개인지 세는 함수인데, map의 원소들은 하나하나가 다 고유한 값이므로 key가 존재하면 1, 존재하지 않으면 0을 리턴한다. ex) if(m.count(key)){}

 

 

2. string::find() 

  반환값
찾은 경우 찾는 문자의 첫번째 인덱스 값
못 찾은 경우 string::npos (no position=쓰레기 값)

 

3. string::substr()

문자열에서 원하는 위치에 있는 문자열을 받아오고 싶다면 substr 함수를 사용한다. 'str.substr(시작 위치, 길이)' 형태로 사용하고, 첫 번째 인수에는 시작 위치(인덱스, 0부터 시작), 두 번째 인수에는 문자 수를 지정한다. 이때, 두 번째 인자인 문자열 길이는 생략할 수 있는데, 생략하는 경우 지정한 위치부터 마지막까지 문자열을 취득할 수 있다.

substr()에 대한 더 자세한 설명은 아래 링크를 참조하자.

 

C++ 문자열 자르기 substr 사용 방법

C++ 문자열을 substr 함수를 사용해 자르는 방법을 알아보겠습니다. substr 문자열에서 원하는 위치에 있는 문자열을 취득하기 위해 substr 함수를 사용합니다. substr 함수 기본적인 사용 방법을 보겠

ponyozzang.tistory.com

 

 

4. 문제 설명

신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다.

  • 각 유저는 한 번에 한 명의 유저를 신고할 수 있습니다.
    • 신고 횟수에 제한은 없습니다. 서로 다른 유저를 계속해서 신고할 수 있습니다.
    • 한 유저를 여러 번 신고할 수도 있지만, 동일한 유저에 대한 신고 횟수는 1회로 처리됩니다.
  • k번 이상 신고된 유저는 게시판 이용이 정지되며, 해당 유저를 신고한 모든 유저에게 정지 사실을 메일로 발송합니다.
    • 유저가 신고한 모든 내용을 취합하여 마지막에 한꺼번에 게시판 이용 정지를 시키면서 정지 메일을 발송합니다.

다음은 전체 유저 목록이 ["muzi", "frodo", "apeach", "neo"]이고, k = 2(즉, 2번 이상 신고당하면 이용 정지)인 경우의 예시입니다.

유저 ID 유저가 신고한 ID 설명
"muzi" "frodo" "muzi"가 "frodo"를 신고했습니다.
"apeach" "frodo" "apeach"가 "frodo"를 신고했습니다.
"frodo" "neo" "frodo"가 "neo"를 신고했습니다.
"muzi" "neo" "muzi"가 "neo"를 신고했습니다.
"apeach" "muzi" "apeach"가 "muzi"를 신고했습니다.

 

 

각 유저별로 신고당한 횟수는 다음과 같습니다.

유저 ID  신고당한 횟수
"muzi" 1
"frodo" 2
"apeach" 0
"neo" 2

위 예시에서는 2번 이상 신고당한 "frodo"와 "neo"의 게시판 이용이 정지됩니다. 이때, 각 유저별로 신고한 아이디와 정지된 아이디를 정리하면 다음과 같습니다.

유저 ID 유저가 신고한 ID 정지된 ID
"muzi" ["frodo", "neo"] ["frodo", "neo"]
"frodo" ["neo"] ["neo"]
"apeach" ["muzi", "frodo"] ["frodo"]
"neo" 없음 없음

따라서 "muzi"는 처리 결과 메일을 2회, "frodo"와 "apeach"는 각각 처리 결과 메일을 1회 받게 됩니다.

이용자의 ID가 담긴 문자열 배열 id_list, 각 이용자가 신고한 이용자의 ID 정보가 담긴 문자열 배열 report, 정지 기준이 되는 신고 횟수 k가 매개변수로 주어질 때, 각 유저별로 처리 결과 메일을 받은 횟수를 배열에 담아 return 하도록 solution 함수를 완성해주세요.

 

 

5. 전체 코드 (written by. YJYoon)

#include <string>
#include <vector>
#include <map>
#include <set>
using namespace std;

map<string, int> reportCnt; // 유저별 신고 당한 횟수
map<string, set<string>> reportLog; // 유저별 신고한 타 유저 리스트

vector<int> solution(vector<string> id_list, vector<string> report, int k) {
    vector<int> answer;
    
    for(string s: report) {
        // 문자열 파싱
        int blank = s.find(' ');            //[1]
        string from = s.substr(0, blank);   //[2]
        string to = s.substr(blank);        //[3]
        
        // from -> to 를 신고한 이력이 없다면 반영
        if(reportLog[from].find(to) == reportLog[from].end()) {  //[4]
            reportCnt[to]++;
            reportLog[from].insert(to);
        }
    }
    
    for(string s: id_list) {
        int res = 0;
        
        // k번 이상 신고 당했다면 결과 메일 +1
        for(string str: reportLog[s])
            if(reportCnt[str] >= k) res++;
        
        answer.push_back(res);
    }
    
    return answer;
}

위 코드의 [1]~[4] 코드를 집중해서 살펴보자. report 벡터 안에는 [신고자 신고대상자] 형태로 신고자와 신고 대상자가 '띄어쓰기'를 구분자로 한 줄로 입력되어 있다. 이를 구분하기 위해 [1]에서 string::find() 매서드를 사용해 띄어쓰기의 인덱스 번호를 받아와 blank에 저장한다. 그리고 신고자, 신고 대상자 각각을 from, to에 저장하기 위해 string::substr() 매서드를 사용한다. [2]에서 from(신고자)을 구하기 위한 substr의 첫 번째 인자는 0, 두 번째 인자는 띄어쓰기 인덱스인 blank를 주어서, 0부터 신고자의 문자열 길이만큼 문자열을 받아와 from에 저장한다. [3]은 [2]과 같은 방식으로 이해하면 된다.

 

마지막으로 [4]번 코드에서는 map 컨테이너인 reportLog에서 find 메서드를 사용한다. reportLog에서 원하는 값이 없다면 이전 신고 내역이 없다는 뜻이므로 새로운 신고 내역을 추가해주는 코드로 이어진다. 이때, if 문에서 find 반환 값이 end()와 같다면 이전 신고 내역을 찾지 못했다는 뜻이다. 

-> 이때, 원하는 값이 있는지 없는지 여부만 찾으면 되기 때문에 iterator를 찾는 find보다 조금 더 단순한 count매서드를 사용하는 것을 더 추천한다.  ex) if(reportLog(from).count(to) == 0)

 

 

6. 마치며

코드 사용을 허락해주신 여준님께 감사드립니다 :) 저는 다음번에 더 유용한 내용으로 찾아오겠습니다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/09   »
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
글 보관함