쌓고 쌓다
[프로그래머스] 신고 결과 받기 C++ 풀이 본문
https://programmers.co.kr/learn/courses/30/lessons/92334
전체 코드
#include <string>
#include <vector>
#include <map>
using namespace std;
vector<int> solution(vector<string> id_list, vector<string> report, int k) {
vector<int> answer;
map<string, int> reportCnt; // 이름별로 신고 당한 횟수
map<string, int> mapping; // 이름별로 index 할당
vector<string> v[1000]; // 내가 신고한 애들
for (int i = 0; i < id_list.size(); i++)
mapping.insert(pair<string, int>(id_list[i], i));
for (int i = 0; i < report.size(); i++)
{
string s1, s2;
bool space = false;
for (int j = 0; j < report[i].length(); j++) // report 내용 분리
{
if (report[i][j] == ' ')
space = true;
else if (space == false)
s1 += report[i][j];
else
s2 += report[i][j];
}
// 중복된 신고인지 검사
bool flag = false;
for (int idx = 0; idx < v[mapping[s1]].size(); idx++)
{
if (v[mapping[s1]][idx] == s2)
flag = true;
}
if (flag == false) // 중복된 신고가 아니면
{
v[mapping[s1]].push_back(s2);
reportCnt[s2]++;
}
}
for (int i = 0; i < id_list.size(); i++)
{
int res = 0;
for (int j = 0; j < v[i].size(); j++)
{
if (reportCnt[v[i][j]] >= k)
res++;
}
answer.push_back(res);
}
return answer;
}
풀이 해설
vector<int> answer;
map<string, int> reportCnt; // 이름별로 신고 당한 횟수
map<string, int> mapping; // 이름별로 index 할당
vector<string> v[1000]; // 내가 신고한 애들
reportCnt : 이름과 매핑해서 그 이름으로 신고당한 횟수를 카운트
mapping : 이름과 매핑해서 고유한 번호를 부여해줄것이다.
v : v[index] -> 고유한 번호에 해당하는 사람이 신고한 애들의 이름들을 vector로 저장할 것이다.
for (int i = 0; i < id_list.size(); i++)
mapping.insert(pair<string, int>(id_list[i], i));
id_list에 담긴 이름들을 순서대로, i로 번호를 매겨 부여해줍니다.
for (int i = 0; i < report.size(); i++)
이제 report에 담긴 순서대로 풀어나갈 겁니다.
string s1, s2;
bool space = false;
for (int j = 0; j < report[i].length(); j++) // report 내용 분리
{
if (report[i][j] == ' ')
space = true;
else if (space == false)
s1 += report[i][j];
else
s2 += report[i][j];
}
s1에는 신고자의 이름, s2에는 신고당한 사람의 이름을 넣을 겁니다.
bool flag를 통해 s1에 문자를 추가할지 s2에 문자를 추가할지 정합니다.
공백이 나타나기 전이라면 s1의 문자이기에 s1에 붙여주고
공백이 나타난 후라면 s2의 이름이니 s2에 붙여줍니다.
그러면 s1과 s2에 신고자와 신고당한 사람의 이름이 완성됩니다.
// 중복된 신고인지 검사
bool flag = false;
for (int idx = 0; idx < v[mapping[s1]].size(); idx++)
{
if (v[mapping[s1]][idx] == s2)
flag = true;
}
신고자가 중복하여 신고한 경우는 1회로 처리하므로
중복 신고를 하였는지 검사를 합니다.
이 신고자가 신고한 애들을 조회하며 중복 신고 유무를 판별합니다.
if (flag == false) // 중복된 신고가 아니면
{
v[mapping[s1]].push_back(s2);
reportCnt[s2]++;
}
중복 신고가 아니라면 이 신고자가 신고한 애들 리스트에 추가해주고, 신고 당한 사람의 신고 당한 횟수를 +1 해줍니다.
for (int i = 0; i < id_list.size(); i++)
{
int res = 0;
for (int j = 0; j < v[i].size(); j++)
{
if (reportCnt[v[i][j]] >= k)
res++;
}
answer.push_back(res);
}
이제 id_list를 순서대로 돌며 이 사람이 신고한 사람이 정지를 당할 사람인지 유무를 판단합니다.
만약 Cnt가 k보다 크다면 정지당한 사람이므로 +1 해주고
이 사람이 신고한 사람들 리스트를 다 돌고
answer에 푸쉬해줍니다.
그러면 answer에 순서대로 메일을 받을 횟수들이 담길 것입니다.
+ 풀며 실수한 것
이 for문의 변수명을 k로 사용하여
이 함수의 매개변수 이름 k와 중복되게 사용하여 한동안 헤맸습니다.
코드를 작성할 때 변수 이름을 유의하여 봐야겠습니다.
'알고리즘 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 크레인 인형뽑기 게임 C++ 풀이 (0) | 2022.06.27 |
---|---|
[프로그래머스] 키패드 누르기 C++ 풀이 (0) | 2022.06.27 |
[프로그래머스] 숫자 문자열과 영단어 C++ 풀이 (0) | 2022.06.25 |
[프로그래머스] 신규 아이디 추천 C++ 풀이 (0) | 2022.06.24 |
[프로그래머스] 로또의 최고 순위와 최저 순위 C++ 풀이 (0) | 2022.06.23 |