신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다.
다음은 전체 유저 목록이 ["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 함수를 완성해주세요.
id_list | report | k | result |
---|---|---|---|
["muzi", "frodo", "apeach", "neo"] | ["muzi frodo","apeach frodo","frodo neo","muzi neo","apeach muzi"] | 2 | [2,1,1,0] |
["con", "ryan"] | ["ryan con", "ryan con", "ryan con", "ryan con"] | 3 | [0,0] |
문제의 예시와 같습니다.
"ryan"이 "con"을 4번 신고했으나, 주어진 조건에 따라 한 유저가 같은 유저를 여러 번 신고한 경우는 신고 횟수 1회로 처리합니다. 따라서 "con"은 1회 신고당했습니다. 3번 이상 신고당한 이용자는 없으며, "con"과 "ryan"은 결과 메일을 받지 않습니다. 따라서 [0, 0]을 return 합니다.
효율성이 좋지 못한 코드
def solution(id_list, report, k):
answer = [0 for i in range(len(id_list))]
report=list(set(report))
idx=[]
cnt=[0 for i in range(len(id_list))]
reported=[]
for i in range(len(report)):
reported.append(report[i].split(' '))
cnt[id_list.index(reported[i][1])]+=1
for j in range(len(cnt)):
if cnt[j]>=k:
idx.append(id_list[j])
for k in range(len(reported)):
for n in range(len(idx)):
if idx[n]==reported[k][1]:
answer[id_list.index(reported[k][0])]+=1
return answer
다른 사람의 풀이를 참고해서 짠 코드
def solution(id_list, report, k):
answer = [0]*len(id_list)
#딕셔너리를 이용하여 신고당한 사람:신고한 사람으로 만들 예정
re={i:[] for i in id_list}
#중복 제거
report=list(set(report))
#re딕셔너리에 신고당한 사람: 신고한 사람 형식으로 넣어주기
#왜냐하면 이후에 for문을 덜 쓰기 위함
for i in range(len(report)):
spl=report[i].split()
re[spl[1]].append(spl[0])
#딕셔너리의 key,value 이용
#id_list 순서대로 넣어놨기 때문에 id_list.index() 이용
#이전에는 안 쪽 for문과 if문의 위치가 바뀌어있었음
# => for문 반복 횟수가 더 많아지기 때문에 if문을 먼저 적는 것이 효율성을 높일 수 있음
#이를 위해서 re의 형식을 신고당한 사람:신고한 사람으로 한 것.
for key,val in re.items():
if len(val)>=k:
for n in val:
answer[id_list.index(n)]+=1
return answer
def solution(id_list, report, k):
answer = [0] * len(id_list)
reports = {x : 0 for x in id_list}
for r in set(report):
#신고 당한 횟수 체크
reports[r.split()[1]] += 1
for r in set(report):
if reports[r.split()[1]] >= k:
answer[id_list.index(r.split()[0])] += 1
return answer
코드는 조금 더 간단해 보이지만 효율성은 비슷한 정도였다.