상세 컨텐츠

본문 제목

[프로그래머스] 1차 뉴스 클러스터링 (2단계)

Programing/알고리즘

by Array 2021. 6. 15. 11:02

본문

문자열 "FRANCE"와 "FRENCH"가 주어졌을 때, 이를 두 글자씩 끊어서 다중집합을 만들 수 있다. 각각 {FR, RA, AN, NC, CE}, {FR, RE, EN, NC, CH}가 되며, 교집합은 {FR, NC}, 합집합은 {FR, RA, AN, NC, CE, RE, EN, CH}가 되므로, 두 문자열 사이의 자카드 유사도 J("FRANCE", "FRENCH") = 2/8 = 0.25가 된다.

 

두문자열을 자르는 것부터 해야한다. 정답지를 보니 여러방법이있는데.

 

자르는 방법에대해서 고민해볼필요성이있었다.

 

입력 형식

  • 입력으로는 str1과 str2의 두 문자열이 들어온다. 각 문자열의 길이는 2 이상, 1,000 이하이다.
  • 입력으로 들어온 문자열은 두 글자씩 끊어서 다중집합의 원소로 만든다. 이때 영문자로 된 글자 쌍만 유효하고, 기타 공백이나 숫자, 특수 문자가 들어있는 경우는 그 글자 쌍을 버린다. 예를 들어 "ab+"가 입력으로 들어오면, "ab"만 다중집합의 원소로 삼고, "b+"는 버린다.
  • 다중집합 원소 사이를 비교할 때, 대문자와 소문자의 차이는 무시한다. "AB"와 "Ab", "ab"는 같은 원소로 취급한다.

 

내용을 확인하니깐.  글자를 자르는 것부터 시작해야했다. 

 

한글자씩 반복문을 돌리면서. 짝수 즉 x%2 == 0 일때 시점 기준으로 두글자의 내용을 가져와서 

정규식을 사용하여 입력형식에 넣을지 아니면 말지를 결정하였다.

function setArr(str){
    let arr = []
    let count = 0;
    let tmp = '';
    let regExp = /^[a-z]*$/;

    for(let i of str.toLowerCase()){
        tmp = tmp + i;
        count ++;

        if(count%2 == 0){
            
            if(regExp.test(tmp)) arr.push(tmp)
            tmp = i;
            count --;
        }
    }

    return arr;
}

다른사람 코드를 보니 작업순서도가 생각보다 복잡하지않은데. 너무 많은양의 코드를 작성한거같다.

 

function strToArr(str){
    return Array.apply(null,Array(str.length-1))
                .map( (x,i) => (str[i]+str[i+1]).toLowerCase() )
                .filter(v=> /^[a-z]+$/.test(v) )   
}

 

다시짠 코드이다. 물론 다른사람꺼 보고 작성하긴 한거다만..

내가원하는 코드인거같다.

 

글자길이만큼 배열갯수를 만들고. 그이후 map을통해 원하는 부분을 만들어서 리턴하며, 

이후 걸러줄 내용을 filter 사용하여 결과를 완성했다.

 

배열은 자주쓸수록 느는거같다..

 

apply 개념을 정확히 이해해야할거같다. 그리고 자바스크립트 String 객체를 좀더 깊숙히 파고들필요성이있는거같다.

 

 

이후 합집합과 교집합 구하는부분은

 

A교집합B 구한뒤 A에서 A교집합B를 뺀 나머지를 합집합에 넣어두고.

합집합에서 B를 더해서 완벽한 합집합을 만들었다.

 

이후 길이를 계산하여 완성했다.

 

function solution(str1, str2) {
    let answer = 0;
    let 시작배열 = setArr(str1);
    let 끝배열 = setArr(str2);

    let 교집합 = [];
    let 합집합 = [];

    시작배열.forEach(v=>{
        if(끝배열.indexOf(v) >= 0) 교집합.push(끝배열.splice(끝배열.indexOf(v),1))
        합집합.push(v)
    })

    끝배열.forEach(v=> 합집합.push(v) )

    if(합집합.length == 0) return 65536
    answer = Math.floor((교집합.length / 합집합.length) * 65536)
    
    return answer
}

이제 다른연습하러..

'Programing > 알고리즘' 카테고리의 다른 글

[백준알고리즘] 2839번 설탕배달 for Python  (0) 2019.06.05

관련글 더보기

댓글 영역