개발공부/코딩테스트 연습문제

[프로그래머스] Level.2 - (1차)뉴스 클러스터링 (JAVA)

ku-na 2022. 1. 19. 15:34

문제 설명과 제한사항

문제가 정말 읽기 싫을정도로 길다..

결론. 1. 문자열 두개 줄거임.

       2. 두 문자열을 2개씩 잘라서 집합 만드셈! ex) abcdef -> [a,b], [b,c], [c,d], [d,e], [e,f]

       3. 자카드 유사도 구해서 65536 곱하셈!

          ㄴ 자카드 유사도 = 교집합/합집합

자세한건 문제 읽어보면 알겠지만 입력 형식을 보면 영문자 이외에는 집합은 버릴거임. 그리고 대문자 소문자 무시할거임!

 

1차 풀이 

import java.util.*;

class Solution {
    public int solution(String str1, String str2) {
        int answer = 0;
        str1 = str1.toLowerCase();
        str2 = str2.toLowerCase();
        List<String> tmp1 = new ArrayList<String>();
        List<String> tmp2 = new ArrayList<String>();

        for(int i = 0; i < str1.length() -1 ; i++){
            String tmp = str1.substring(i,i+2);
            if(tmp.matches("[a-z]{2,2}")){
                tmp1.add(tmp);
            }
        }
        for(int i = 0; i < str2.length() -1 ; i++){
            String tmp = str2.substring(i,i+2);
            if(tmp.matches("[a-z]{2,2}")){
                tmp2.add(tmp);
            }
        }
       
        Collections.sort(tmp1);
        Collections.sort(tmp2);
        
        int i = 0;
        int j = 0;
        
        while(i < tmp1.size() && j < tmp2.size()){
            if(tmp1.get(i).compareTo(tmp2.get(j)) == 0){
                answer++;
                i++;
                j++;
            }
            else if(tmp1.get(i).compareTo(tmp2.get(j)) > 0){
                j++;
            }
            else if(tmp1.get(i).compareTo(tmp2.get(j)) < 0){
                i++;
            }
        }
        
        if(answer == 0) return 65536;
        else return (int)(65536 * (double)answer/(tmp1.size() + tmp2.size() - answer));
    }
}

++

으으!!! 또!! 또 하드코딩하지 또!!! 으이구..

풀이 과정은 다음과 같음

1. 두 문자열 소문자로 toLowerCase(); -> 또 까먹어서 다시 찾아봄 ㅋㅋ

2. 두 문자열을 정제해서 list에 담음 : 

            String tmp = str1.substring(i,i+2);
            if(tmp.matches("[a-z]{2,2}")){
                tmp1.add(tmp);
            }

  -> tmp.matches("[a-z]{2,2}") : 이것은 내코드가 아님 찾아본 것임. matches는 문자열이랑 비교해서 판단해주는 거임

 그래서 [a-z] : 영어 소문자만 {2,2}<-이건 모르겠는데 아마 2글자겠지..? 정제한 데이터들만 tmp에 넣은 것임

3. sort : ㅋㅋㅋ 리스트 정렬할때 마다 맨날 tmp1.sort() 이딴식으로 씀 ㅋㅋㅋㅋㅋ 

    Collections.sort(리스트); 다음부턴 안까먹길.

4. 반복해서 비교 후 리턴~

움.. 찾아봐서 도움이 됐던 정보는 matches 정도..?

근데 문제가 있음

실패함 ㅋㅋㅋㅋ

2개는 내일 다시 생각해 볼 것임 오늘은 저 쓸데없이 더럽게 긴 문제 읽느라 머리가 아프기 때문임~

 

++

import java.util.*;

class Solution {
    public int solution(String str1, String str2) {
        List<String> list1 = new ArrayList<String>();
        List<String> list2 = new ArrayList<String>();
        str1 = str1.toLowerCase();
        str2 = str2.toLowerCase();
       
        for(int i = 0; i < str1.length() -1 ; i++){
            String tmp = str1.substring(i,i+2);
            if(tmp.matches("[a-z]{2,2}")){
                list1.add(tmp);
            }
        }
        for(int i = 0; i < str2.length() -1 ; i++){
            String tmp = str2.substring(i,i+2);
            if(tmp.matches("[a-z]{2,2}")){
                list2.add(tmp);
            }
        }
        
        Collections.sort(list1);
        Collections.sort(list2);
        
        List<String> inter = new ArrayList<>();
        List<String> union = new ArrayList<>();
        
        for(int i=0; i<list1.size(); i++) {
            String str = list1.get(i);
            if(list2.remove(str)) {
                inter.add(str);
            }
            union.add(str);
        }
        for(int i=0; i<list2.size(); i++) {
            String str = list2.get(i);
            union.add(str);
        }
        
        if(union.size() == 0)
            return 65536;
        else
            return (int)(65536*((double)inter.size() / (double)union.size()));

    } 
}

성공 코드... 하고 싶은 말이 정말 많다.

import java.util.*;

class Solution {
    public int solution(String str1, String str2) {
        int answer = 0;
        List<String> list1 = new ArrayList<String>();
        List<String> list2 = new ArrayList<String>();
        ArrayList<String> inter = new ArrayList<>();
        ArrayList<String> union = new ArrayList<>();
        str1 = str1.toLowerCase();
        str2 = str2.toLowerCase();
       
        for(int i = 0; i < str1.length() -1 ; i++){
            String tmp = str1.substring(i,i+2);
            if(tmp.matches("[a-z]{2,2}")){
                list1.add(tmp);
            }
        }
        for(int i = 0; i < str2.length() -1 ; i++){
            String tmp = str2.substring(i,i+2);
            if(tmp.matches("[a-z]{2,2}")){
                list2.add(tmp);
            }
        }
        
        int hap = 0;
        int zero = 0;
        Collections.sort(list1);
        Collections.sort(list2);
        
        for(int i=0; i<list1.size(); i++) {
            String str = list1.get(i);
            if(list2.remove(str)) {
                zero++;
            }
            hap++;
        }
        for(int i=0; i<list2.size(); i++) {
            hap++;
        }
        
        double rs = 0;
        if(zero == 0)
            rs = 1;
        else
            rs = (double)zero / (double)hap;
        
        return (int)(rs*65536);
    } 
}

테스트 5, 13 실패 코드.. 우선 다른점이라 함은

성공코드는 List에 넣고 그 사이즈를 가지고 계산하고 실패코드는 개수만 카운트하는건데

그 차이점으로 자꾸 실패하니까 진짜 열받았다.. 테스트케이스를 볼 순 없으니 이것 저것 다 해봤는데

다른 코드의 문제는 없었고 저거 하나만 자꾸 저러니까 열받는다