본문 바로가기
알고리즘 부셔버렷/ProblemSolving

[프로그래머스] 신고 결과 받기 (문제 해결 과정, 코드 전문, C++)

by Unagi_zoso 2022. 5. 26.

 

  문제 설명

 

 

본 문제는 프로그래머스의 신고 결과 받기 문제입니다.

입력데이터유저들의 ID 정보를 가진 vector<string> id_list, 신고자와 신고받은자의 정보가 를 가진 vector<string> report, 정지기준의 신고횟수 int k입니다.

인원이 주어지고 인원들끼리 서로 신고를하며 한 유저가 k개 이상의 신고를 받게되면 그 유저를 신고한 유저들에게 신고적용문자가 들어가게 됩니다.

반환값은 이 때 각 유저들이 신고적용문자를 얼마나 받았는지를 보내주면 됩니다.

 

이 때 주의할 점한 유저가 여러 사람을 신고할 수 있으며. 그리고 같은 사람을 여러번 신고할 수 있는데 이는 중복으로 여겨 한 번의 신고만 인정됩니다. 

 

신고자와 신고받은 자의 정보를 가진 report의 구조는 

vector 한 칸에 "신고자 신고받은 자"의 형식으로 되어있습니다.

 

report 구조

 

 

 

 

  해결 과정

 

 

 

제가 문제를 해결하면서 설계한 해결과정입니다.

 

핵심적인 내용은 report의 데이터에서 파싱을 거쳐 각 각의 데이터를 report_log라는 map<string, set<string>>데이터구조에 저장됩니다. report_log의 first에는 신고받은 자를, second에는 신고자들을 set으로 받아 관리합니다. 이후 report_log의 전체를 순회하며 set의 size가 k이상인 경우 second에 존재하는 신고자들의 answer 값을 각 각 하나씩 증가시킵니다.

 

이후 answer 값을 반환합니다.

 

 

여기까지가 전체적인 문제해결의 과정입니다.

 

 

 

  코드 전문

 

 

#include <string>
#include <vector>
#include <set>
#include <map>
#include <iostream>

using namespace std;

vector<int> solution(vector<string> id_list, vector<string> report, int k) {
    map<string, set<string>> report_log;
    map<string, int> id_idx;
    vector<int> answer;
    
    for (auto just_count : id_list)
    {
        answer.emplace_back(0);
    }
    
    //id set idx
    for (int i = 0; i < id_list.size(); i++)
    {
        id_idx[id_list[i]] = i;
    }
    
    //report parsing
    for (int i = 0; i < report.size(); i++)
    {
        int blank = report[i].find(" ");
        report_log[report[i].substr(blank, report[i].size() - 1)].insert(
                   report[i].substr(0, blank));
    }
    
    for (auto reportees : report_log)
    {
        auto reporters = reportees.second;
        if (reporters.size() >= k)
        {
            for (auto r : reporters)
                answer[id_idx[r]]++;
        }
    }

    return answer;
}

 

 

 

 

  느낀 점 (잡설 99% , 배운점 1%(많은 편))

 

 

더보기

set이나 map같은 stl을 써볼 수 있어서 좋은 경험이였네요

map의 경우 [] 연산자가 지원되어 생성이나 접근이 가능했습니다. set은 그러지 못해서 조금 햇갈렸네요.

set의 경우 insert() 함수를 같이 사용하여 데이터를 삽입하였습니다. 

그냥 set, map이 존재하고 ( 보통 균형이진트리 같은 트리구조로 구현), unordered set,map(해시테이블)이 있는데

이번의 경우 전체순회가 필요하고 해시테이블 생성 같은 추가적인 공간도 피하고 싶어 그냥 set과 map을 사용하였습니다. set, map, unordered..들은 중복도 막아줘서 이번 문제에서는 아주 적절했다 생각합니다.

여담으로 set, map에서의 find()함수를 사용시 못 찾는 경우 end() 반복자를 반환하네요.

 

문자열 파싱이란 것도 해봤는데 stl의 편리함을 몸소 채험할 수 있었습니다. 다양한 문자열 문제에서 사용할 수 있겠습니다.

좀 더 자세히 적자면 string에서의 find() 함수를 통하여 인자로 원하는 문자를 넣으면 그 문자열 내 그 문자의 인덱스를

반환하였습니다. 이를 기준으로 string의 substr()함수를 통하여 문자열을 가르고 서로 다른 string 객체로 만들었습니다.

find()로 문자를 못찾을땐 string npos를 반환하는군요.

 

마지막으로 코드 마지막 for문 부분의 reportees와 reporters의 네이밍이 적절했나 안했나가 마음에 걸리네요.

 

 

 

 

긴 글 읽어주셔서 감사합니다. 

부족한 점이 있다면 부디 알려주시면 감사하겠습니다.

 

댓글