신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다.
각 유저는 한 번에 한 명의 유저를 신고할 수 있습니다.
신고 횟수에 제한은 없습니다. 서로 다른 유저를 계속해서 신고할 수 있습니다.
한 유저를 여러 번 신고할 수도 있지만, 동일한 유저에 대한 신고 횟수는 1회로 처리됩니다.
k번 이상 신고된 유저는 게시판 이용이 정지되며, 해당 유저를 신고한 모든 유저에게 정지 사실을 메일로 발송합니다.
유저가 신고한 모든 내용을 취합하여 마지막에 한꺼번에 게시판 이용 정지를 시키면서 정지 메일을 발송합니다.이용자의 ID가 담긴 문자열 배열 id_list, 각 이용자가 신고한 이용자의 ID 정보가 담긴 문자열 배열 report, 정지 기준이 되는 신고 횟수 k가 매개변수로 주어질 때, 각 유저별로 처리 결과 메일을 받은 횟수를 배열에 담아 return 하도록 solution 함수를 완성해주세요.
최초 풀이
(1단계) 신고받은 횟수와 신고한 id를 넣을 딕셔너리 생성
(2단계) 신고받은 횟수와 신고한 id(중복제거)를 딕셔너리에 넣어줌
(3단계) k번 이상 신고받은 아이디만 남김
(4단계) 아이디별 메일 수신 횟수 카운트
def solution(id_list, report, k): answer = [0] * len(id_list) reported_id = dict() report_id = dict() # 신고받은 횟수와 신고한 id를 넣을 딕셔너리 생성 for id in id_list: reported_id[id] = 0 report_id[id] = list() # 신고받은 횟수와 신고한 id(중복제거)를 딕셔너리에 넣어줌 for rep in report: rep_id, reped_id = rep.split(' ') if report_id[reped_id].count(rep_id) == 0: reported_id[reped_id] += 1 report_id[reped_id].append(rep_id) # k번 이상 신고받은 아이디만 남김 reported_id = {reped_id : count for reped_id, count in reported_id.items() if count >= k} # 아이디별 메일 수신 횟수 카운트 for reped_id in reported_id.keys(): for id in report_id[reped_id]: answer[id_list.index(id)] += 1 return answer
알고리즘 효율화를 위해 Chat GPT에 개선점을 물었고 아래와 같은 답을 얻었다.
코드를 개선할 수 있는 몇 가지 점을 제안해 드리겠습니다. 여기에는 코드의 효율성, 가독성, 그리고 가능한 예외 처리 등이 포함됩니다.
중복 방지와 데이터 구조 선택
현재는 각 사용자가 신고한 ID를 리스트에 저장하고 중복 여부를 리스트의 count 메서드로 확인합니다. 대신, 신고한 사용자를 set으로 저장하면 중복 확인이 훨씬 효율적입니다.불필요한 반복문 제거
reported_id 딕셔너리를 report_id 딕셔너리와 병합할 수 있습니다. 이는 단일 반복문을 통해 처리할 수 있습니다.코드의 가독성 향상
변수 이름을 좀 더 직관적으로 변경하고, 불필요한 변수 사용을 줄일 수 있습니다.예외 처리
현재 코드는 id_list에 존재하지 않는 사용자가 신고된 경우를 처리하지 않습니다. 그런 경우를 처리할 수 있는 로직을 추가하는 것이 좋습니다.
def solution(id_list, report, k): answer = [0] * len(id_list) report_count = {id: 0 for id in id_list} reports_received = {id: set() for id in id_list} for rep in report: reporter, reported = rep.split() if reporter not in reports_received[reported]: reports_received[reported].add(reporter) report_count[reported] += 1 for reported, count in report_count.items(): if count >= k: for reporter in reports_received[reported]: answer[id_list.index(reporter)] += 1 return answer