[프로그래머스] level1 - 신고 결과 받기

올랜도·2022년 7월 25일
1
post-thumbnail

주의) 본 글쓴이는 이제 막 자바로 코테준비를 하는 사람이므로 상당히 코드가 괴상할 수 있습니다.

행여나 지나치시다 보시게 된다면 무자비한 지적 해주시면 감사하겠습니다.

프로그래머스 level1 - 신고 결과 받기

1. 문제 및 조건








2. 사전 준비

게시판 이용자를 불량신고하고 신고에 대한 결과를 메일로 발송하는 시스템을 개발 하는 것이 목적이다.
조건을 보며 고민하며 일단 누가 누구를 신고했는지, 그리고 누가 얼만큼 신고를 당했는지 알아야겠다고 생각했다.
그리고 똑같은 사람을 계속 신고하는 것은 카운트가 안된다는 조건이 필요함을 생각했다.

  1. 중복신고는 카운트가 증가하지 않는다
  2. 누가 누구를 신고했는지, 누가 얼만큼 신고당했는지 기록해야 한다.
  3. 신고에 대한 카운트가 k이상일 경우 신고한 사람에게 메일이 가야한다.

이렇게 세가지의 조건을 뼈대로 잡고 구현을 시작했다.
중복에 대한 것은 자바의 경우 stream을 통한 중복 제거를 구현 가능했다.
그리고 key-value타입의 변수를 선언하여 value에 리스트를 담아 신고한 사람을 담고, 누가 얼만큼 신고당했는지 구현하고자 했다.
마지막으로 위의 동작이 끝나면 k이상 신고당한 사람에 대해 반복문을 통해 값을 증가시키며 결과 값을 반환한다.

그리고 여기서 문제가 하나 발생했다.
원래는 HashMap을 통해서 key-value쌍을 이루려 했는데 이렇게 구현을 하게 되면 순서의 보장이 어렵다는 것이었다.
어쩐지 계속 테스트 케이스와 내용물은 똑같은데 순서가 달라서 애를 먹었는데 이런 비밀이 숨겨져 있었다.
따라서 이를 보완하기 위한 LinkedHashMap을 통해 두개의 변수를 구성했다.







3. 코드 작성

		//결과 받는 변수
        int[] answer = new int[id_list.length];
		
        //누구를 신고했는지를 구하기위한 변수 log, 누가 얼만큼 신고를 받았는지 세는 cnt
        LinkedHashMap<String, ArrayList<String>> log = new LinkedHashMap<String, ArrayList<String>>();
        Map<String, Integer> cnt = new HashMap<String, Integer>();

        for (String s : id_list) {
            log.put(s, new ArrayList<>());
            cnt.put(s, 0);
        }

해당 코드에서는 향상된 for문을 바탕으로 각각의 HashMap에 값을 추가하였다.

		String[] setReport = Arrays
                .stream(report)
                .distinct()
                .toArray(String[]::new);

그리고 Arrays.stream을 통해 중복에 대한 제거를 마친 새로운 배열을 초기화했다.

		for (String s : setReport) {
            String[] reportArr = s.split(" ");

            log.get(reportArr[0]).add(reportArr[1]);
            cnt.put(reportArr[1], cnt.get(reportArr[1]) + 1);
        }

여기서는 새로운 배열에서 향상된 for문으로 하나씩 값을 가져와 문자열을 분리 후
앞서 초기화한 HashMap logcnt에 값을 추가하고 더해주었다.

 		int idx = 0;

        for(String user : log.keySet()){
            for(String c : cnt.keySet()){
                if(cnt.get(c) >= k && log.get(user).contains(c))
                    answer[idx] ++;
            }
            idx ++;
        }

        return answer;

마지막으로 메일을 보내는 로직이다.
이중 for문을 구성하였고 첫번째 for문에서는 신고한 사람의 배열을 value값으로 갖는 key를 가져온다.
두번째 for문에서는 개개인별 신고당한 횟수를 가져오며 배열안에 있는 사람이 신고당한 횟수가 k이상일 경우
idx번째 사람이 받은 메일의 주소를 1만큼 증가시키도록 하였다.

마지막으로 값을 반환한다.







4. 전체 코드

import java.util.*;

class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {

        int[] answer = new int[id_list.length];

        LinkedHashMap<String, ArrayList<String>> log = new LinkedHashMap<String, ArrayList<String>>();
        Map<String, Integer> cnt = new HashMap<String, Integer>();

        for (String s : id_list) {
            log.put(s, new ArrayList<>());
            cnt.put(s, 0);
        }

        String[] setReport = Arrays
                .stream(report)
                .distinct()
                .toArray(String[]::new);


        for (String s : setReport) {
            String[] reportArr = s.split(" ");

            log.get(reportArr[0]).add(reportArr[1]);
            cnt.put(reportArr[1], cnt.get(reportArr[1]) + 1);
        }

        int idx = 0;

        for(String user : log.keySet()){
            for(String c : cnt.keySet()){
                if(cnt.get(c) >= k && log.get(user).contains(c))
                    answer[idx] ++;
            }
            idx ++;
        }

        return answer;
    }
}






5.결과

생각했던것보다 시간이 많이걸려서 중간에 시간초과가 터지지않을까 걱정했지만

다행히 통과 하였다.

profile
☂️생존주의 개발자

0개의 댓글