코딩테스트(Level 0~1)

[JAVA, Programmers] 신고 결과 받기(자바, kakao)

justdoIT0730 2022. 11. 22. 20:43
728x90
728x90

1. 문제 설명

신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다.

 - 각 유저는 번에 명의 유저를 신고할 있습니다.

- k 이상 신고된 유저는 게시판 이용이 정지되며, 해당 유저를 신고한 모든 유저에게 정지 사실을 메일로 발송합니다.

 

다음은 전체 유저 목록이 ["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 함수를 완성해주세요.

 

2. 제한사항

2 ≤ id_list 길이 ≤ 1,000

1 ≤ report 길이 ≤ 200,000

1 ≤ k ≤ 200, k 자연수입니다.

 

return 하는 배열은 id_list 담긴 id 순서대로 유저가 받은 결과 메일 수를 담으면 됩니다.

 

3. 입출력

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]

 

4. 입출력 설명

- 입출력 #1

문제의 예시와 같습니다.

- 입출력 #2

"ryan" "con" 4 신고했으나, 주어진 조건에 따라 유저가 같은 유저를 여러 신고한 경우는 신고 횟수 1회로 처리합니다. 따라서 "con" 1 신고당했습니다. 3 이상 신고당한 이용자는 없으며, "con" "ryan" 결과 메일을 받지 않습니다. 따라서 [0, 0] return 합니다.

 

5. 풀이

import java.util.*;
class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
        int [] answer = new int [id_list.length];	//answer 크기 지정;
		HashSet<String> re = new HashSet<String>(); //report 중복값 제거 작업;
		for(int i =0; i<report.length;i++) {
			re.add(report[i]);
		}
		
		Iterator<String> rei = re.iterator();
		String[] Re=new String[re.size()];

		while (rei.hasNext()) {						//report 중복 제거
			for(int i=0; i<re.size(); i++) {
				Re[i] = rei.next();
			}
		}

		
		String [][] list = new String [id_list.length][Re.length];  //id_list에서 각 인원이 Re만큼 신고한 내역 저장
		for(int i=0; i<id_list.length; i++) {//id_list 만큼 반복
			for(int t =0; t<Re.length; t++) { //	report만큼 반복
				if(Re[t]!=null&&id_list[i].equals(Re[t].substring(0, id_list[i].length()))) {//id_list[i]와 report[i](앞자리만) 같다면
						list[i][t]=Re[t].substring(id_list[i].length()+1);
				}
			}
		}

		int cnt =1;
		int [][]b = new int [id_list.length] [Re.length];
		
		for(int i =0; i<id_list.length; i++) {//a의 배열 중 대상 선택
			for(int t =0; t<Re.length; t++) {
				for(int c=0; c<id_list.length; c++) {//a배열 중 비교할 요소 선택
					for(int g =0; g<Re.length; g++) {
						if(list[i][t]!=null&&list[i][t].equals(list[c][g])) {
							b[i][t]+=cnt;
						}
					}
				}
			}
		}
        
		for(int i =0; i<id_list.length; i++) {
			for(int t =0; t<Re.length; t++) {
				if(b[i][t]>=k) {
					answer[i]++;
				}
			}
		}
        return answer;
    }
}

 

5.1 재풀이

1. report 내 중복 제거

2. id_list 내 이름과 report 내 신고자 이름이 같다면, 신고당한 이름을 list배열에 저장

3. list 배열 내 요소가 중복되고 그 수가 k 이상일 때의 경우 그 수를 합산하여 answer에 저장

4. 결과 : 런타임 오류 

 

6. 최종 풀이

나름 해결한다고 했는데, 너무 1차원 적이고 생각나는 대로~ 손가는 대로~ 저질러버렸으니 당연한 결과이기도 하다,,

실행 시간을 줄이고자 list 크기를 줄이거나 list 배열을 생성 시 바로 3번의 방식을  진행해보려고 하였으나, 다른 함수를 사용해야겠다는 생각이 들었다.

HashMap의 사용과 보다 간단한 알고리즘을 이해하기 쉽게 정리하신 분의 정보를 참고하였다..

편의상 report 내 "muzi frodo" 중  muzi(신고자) frodo(범죄자)라고 하였다..

 

import java.util.*;
class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
        int[] answer = new int[id_list.length];
        Map<String, HashSet<String>> map = new HashMap<>(); 		//1
        Map<String, Integer> idxMap = new HashMap<>();
 
        for (int i = 0; i < id_list.length; i++) {			//2
            String name = id_list[i];
            map.put(name, new HashSet<>());
            idxMap.put(name, i);
        }
 
        for (String s : report) {					//3
            String[] str = s.split(" ");
            String user = str[0];
            String singo = str[1];
            map.get(singo).add(user);
        }	
 
        for (int i = 0; i < id_list.length; i++) {			//4
            HashSet<String> send = map.get(id_list[i]);
            if (send.size() >= k) {
                for (String name : send) {
                    answer[idxMap.get(name)]++;
                }
            }
        }
        return answer;
    }
}

//1 

Map<String, HashSet<String>> map = new HashMap<>();  

Map<(key 값 : user ID, 범죄자), (value 값 : key를 신고한 사람 user ID)> map

 

Map<String, Integer> idxMap = new HashMap<>();

Map<key 값 : user ID), (value 값 : id_list에 접근하기 위한 임의 인덱스 값 : 범죄자)> idxMap

 

//2

id_list의 요소를 name에 저장

map.put(name, new HashSet<>());   →    map에 key 값 : name, value 값 : 선언 시 설정한 값 저장

  (map 출력 시 ⇢ {muzi=[], neo=[], frodo=[], apeach=[]})

idxMap.put(name, i);   →    idxMap에 key 값 : name, value 값 : 인덱스 값 저장

  (idxMap 출력 시 ⇢ {muzi=0, neo=3, frodo=1, apeach=2})

 

//3

report 내 요소를 s에 담는다.

String[] str = s.split(" ");   →    " "를 기준으로 각각 str [0](신고당한 사람), str[i](이용자를 신고한 사람)에 저장한다.

 

String user = str[0];    →    singo에게 신고당한 사람 : 범죄자

String singo = str[1];    →    user를 신고한 사람 : 신고자

map.get(singo).add(user);    →    map 내 singo와 같은 요소에 신고당한 사람을 저장해라

  (map 출력 시 ⇢{muzi=[apeach], neo=[muzi, frodo], frodo=[muzi, apeach], apeach=[]})

 

//4 

send에 신고자를 저장

신고자가 저장된 send의 크기(send.size())가 k 이상이라면

idxMap의 인덱스 값을 name으로 불러온 뒤

send.size만큼 1씩 더하여 최종 메일 받을 수를 저장하면 된다.

 

 

 

다시 정리를 하면서 단순한 알고리즘뿐만 아니라 Map, hashmap 등 생소한 함수도 공부하게 되었다.. 

더 많이 알고 아는 것을 더 많이 자유롭게 사용할 수 있도록 하여야겠다...

 

728x90

[출처]

https://soft91.tistory.com/16

 

[JAVA] Map,Set - HashMap, HashSet 간략 정리

[JAVA] Map,Set - HashMap, HashSet 간략 정리 HashMap : 키 값과 데이터를 사용하여 HashTable의 값을 찾음. HaspMap 객체명 = new HaspMap(배열 수); /* 타입 파라미터를 프리미티브 타입으로 정하면 안됨 *//* ()는 50이

soft91.tistory.com

https://yeoeun-ji.tistory.com/m/113

 

[Java 자바] 프로그래머스 > Lv.1 신고 결과 받기

https://programmers.co.kr/learn/courses/30/lessons/92334 코딩테스트 연습 - 신고 결과 받기 문제 설명 신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니

yeoeun-ji.tistory.com

https://codechacha.com/ko/java-map-hashmap/#1-hashmapput

 

Java - HashMap 사용 방법 및 예제

HashMap은 Map의 일종으로 key와 value의 쌍으로 이루어진 데이터를 보관합니다. HashMap은 데이터의 저장순서를 보장하지 않으며 null을 허용합니다. 또한 put, putAll, get, remove, keySet, values 등의 API들을 제

codechacha.com

https://reakwon.tistory.com/151

 

[Collection] 이것만 알면 해시맵(HashMap) 정복 가능 - HashMap의 특징, 사용법 예제

해시맵(HashMap) 해시맵은 이름 그대로 해싱(Hashing)된 맵(Map)입니다. 여기서 맵(Map)부터 짚고 넘어가야겠죠? 맵이라는 것은 키(Key)와 값(Value) 두 쌍으로 데이터를 보관하는 자료구조입니다. 여기서

reakwon.tistory.com

 

728x90
728x90