th42500의 TIL

[Java] 2018 KAKAO BLIND RECRUITMENT - [1차] 뉴스 클러스터링 (Lv2) 본문

Algorithm/Programmers

[Java] 2018 KAKAO BLIND RECRUITMENT - [1차] 뉴스 클러스터링 (Lv2)

th42500 2022. 8. 5. 23:49

문제를 잘못 읽어서 삽질 좀 했던 문제....💦

 

https://school.programmers.co.kr/learn/courses/30/lessons/17677

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

✔ 입출력 예시

피로도 입출력 예시

 

 

💡 포인트

1️⃣ 예시에서는 숫자로 이루어진 집합이었지만 우리는 오직 문자인 경우에만 다중 집합을 구해야 함

2️⃣ 문자의 대소문자는 구분하지 않고 비교

3️⃣ 두 집합을 원소를 모두 합했을 때 = 합집합 + 교집합

 

 

❓ 풀이방법

1️⃣ 문자열을 모두 소문자로 바꾸기

      👉 대소문자 구분없이 비교하기 위해서

2️⃣ 각 문자열을 2글자씩 끊어서 List에 담기

3️⃣ 교집합의 개수 구하기

      👉 첫번째 리스트의 원소가 두번쨰 리스트에 포함되어 있다면 중복되는 원소를 두번째 리스트에서 지워주고

            교집합의 개수를 나타내는 변수  + 1

4️⃣ 합집합의 개수 구하기

      👉 첫번째 리스트의 길이와 중복된 원소가 지워진 두번째 리스트의 길이를 합치기

5️⃣ 두 리스트 모두 공집합이라면 자카드 유사도가 1이므로 65536 반환

6️⃣ 두 리스트 중 하나라도 공집합이 아니라면 자카드 유사도(교집합/합집합)를 구한 후 65536 곱하고 정수부분만 return

 

 

❗ 결과

   👉 테스트 통과

 

 

✔ 소스코드

import java.util.ArrayList;
import java.util.List;

public class Solution { // 뉴스 클러스터링

	public static void main(String[] args) {
		String str1 = "FRANCE";
		String str2 = "french";
//		String str1 = "handshake";
//		String str2 = "shake hands";
//		String str1 = "aa1+aa2";
//		String str2 = "AAAA12";
//		String str1 = "E=M*C^2";
//		String str2 = "e=m*c^2";

		System.out.println(solution(str1, str2));
	}

	private static int solution(String str1, String str2) {
		// 1. 문자열을 모두 소문자로 바꿔주기 (대소문자 구분없이 비교하기 위해)
		str1 = str1.toLowerCase();
		str2 = str2.toLowerCase();
		
		// 2. 각 문자열을 2글자씩 끊어서 List에 담아주기
		List<String> list1 = new ArrayList<>();
		for(int i = 0; i<str1.length()-1; i++) {
			String s = str1.substring(i, i+2);
			if(s.matches("(.*)[^a-z](.*)") || s.trim().length() < 2) {
				continue;
			}
			list1.add(s);
		}
		List<String> list2 = new ArrayList<>();
		for(int i = 0; i<str2.length()-1; i++) {
			String s = str2.substring(i, i+2);
			if(s.matches("(.*)[^a-z](.*)") || s.trim().length() < 2) {
				continue;
			}
			list2.add(s);
		}

		// 3. 교집합 개수 구하기 (list1의 원소가 list2에 포함되어 있다면 중복되는 원소를 list2에서 지워주고 교집합 변수 +1)
		int inter = 0;
		for(String s: list1) {
			if(list2.contains(s)) {
				list2.remove(s);
				inter++;
			}
		}
		
		// 4. 합집합 개수 구하기 (list1과 중복된 원소가 지워진 list2의 길이를 합치기)
		int union = list1.size() + list2.size();
		
		// 5. 두 리스트 모두 공집합이라면 자카드 유사도가 1이므로 65536 return
		if(union == 0) {
			return 65536;
		} else {  // 6. 두 리스트 중 하나라도 공집합이 아니라면 자카드 유사도(교집합/합집합) 구한 후 65536 곱하고 정수부분만 return
			double j = (double)inter/(double)union; 
			j *= 65536;
		
			return (int)Math.floor(j);
		}
	}

}

 

문제의 예시에서는 숫자로 이루어진 집합들을 이용해서 설명했지만 우리가 구해야할 출력의 결과들은 오직 문자로만 이루어진 다중집합이어야 한다...

문제의 내용을 자세히 읽지 않고 숫자가 들어있는 문자열까지 포함하여 삽질했던 나....😢 

앞으로는 문제를 잘 읽자는 교훈을 얻게 된 문제였다...

Comments