본문 바로가기
Problem Solving/프로그래머스

[프로그래머스 | 파이썬 / 자바스크립트] [1차] 뉴스 클러스터링(2018 KAKAO BLIND RECRUITMENT/ level 2)

by 청량리 물냉면 2023. 2. 28.
반응형
문제

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

 

프로그래머스

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

programmers.co.kr

 

 

🐍파이썬
def solution(str1, str2):
    # 두글자씩 쌍 만들기. 알파벳이 아닌 글자가 포함된 경우 pass
    str1Arr = [str1[i:i+2].upper() for i in range(len(str1)-1) if str1[i:i+2].isalpha()]
    str2Arr = [str2[i:i+2].upper() for i in range(len(str2)-1) if str2[i:i+2].isalpha()]
    # str1Arr, str1Arr 각 원소의 갯수 카운트
    str1Dic = {i:str1Arr.count(i) for i in str1Arr}
    str2Dic = {i:str2Arr.count(i) for i in str2Arr}
    kyo, hap = 0, 0
    for i in str1Dic.keys():
        if i in str2Dic.keys():
            kyo += min(str1Dic[i], str2Dic[i])  # 동일원소 존재 시 교집합
            hap += max(str1Dic[i], str2Dic[i])  # 동일원소 존재 시 합집합
        if i not in str2Dic.keys(): #str1 단독
            hap += str1Dic[i]
    for j in str2Dic.keys():
        if j not in str1Dic.keys(): #str2 단독
            hap += str2Dic[j]
    # zero divide 에러 피하기 위해 hap == 0일 경우 예외 처리
    return 65536 if hap == 0 else int(65536 * (kyo / hap))

def solution(str1, str2):
    # 두글자씩 쌍 만들기. 알파벳이 아닌 글자가 포함된 경우 pass
    str1Arr = [str1[i:i+2].upper() for i in range(len(str1)-1) if str1[i:i+2].isalpha()]
    str2Arr = [str2[i:i+2].upper() for i in range(len(str2)-1) if str2[i:i+2].isalpha()]
    # str1Arr, str1Arr 각 원소의 중복제거
    str1Set = set(str1Arr)
    str2Set = set(str2Arr)
    kyo, hap = 0, 0
    for i in str1Set:
        if i in str2Arr:
            kyo += min(str1Arr.count(i), str2Arr.count(i))  # 동일원소 존재 시 교집합
            hap += max(str1Arr.count(i), str2Arr.count(i))  # 동일원소 존재 시 합집합
        else: #str1 단독
            hap += str1Arr.count(i)
    for j in str2Set:
        if j not in str1Arr: #str2 단독
            hap += str2Arr.count(j)
    # zero divide 에러 피하기 위해 hap == 0일 경우 예외 처리
    return 65536 if hap == 0 else int(65536 * (kyo / hap))

 

 

다른 풀이 방법

import re
import math

def solution(str1, str2):
    str1 = [str1[i:i+2].lower() for i in range(0, len(str1)-1) if not re.findall('[^a-zA-Z]+', str1[i:i+2])]
    str2 = [str2[i:i+2].lower() for i in range(0, len(str2)-1) if not re.findall('[^a-zA-Z]+', str2[i:i+2])]

    gyo = set(str1) & set(str2)	#교집합
    hap = set(str1) | set(str2)	#합집합

    if len(hap) == 0 :
        return 65536

    gyo_sum = sum([min(str1.count(gg), str2.count(gg)) for gg in gyo])
    hap_sum = sum([max(str1.count(hh), str2.count(hh)) for hh in hap])

    return math.floor((gyo_sum/hap_sum)*65536)

💡 re 모듈

정규식을 사용하기 위한 모듈

findall(정규식 패턴, 문자열)

정규식 패턴에 맞는 문자열을 모두 찾아서 리스트로 반환


from collections import Counter
def solution(str1, str2):
    # make sets
    s1 = [str1[i:i+2].lower() for i in range(len(str1)-1) if str1[i:i+2].isalpha()]
    s2 = [str2[i:i+2].lower() for i in range(len(str2)-1) if str2[i:i+2].isalpha()]
    if not s1 and not s2:
        return 65536
    c1 = Counter(s1)
    c2 = Counter(s2)
    answer = int(float(sum((c1&c2).values()))/float(sum((c1|c2).values())) * 65536)
    return answer

💡 Count 객체

중복된 데이터가 저장된 배열을 인자로 넘기면 각 원소가 몇 번씩 나오는지 저장된 객체를 반환

Counter(["a", "b", "c", "a", "a", "b"])
# Counter({'a': 3, 'b': 2, 'c': 1})

참고: https://www.daleseo.com/python-collections-counter/

 

 

🐥자바스크립트
function solution(str1, str2) {
    // 알파벳 체크 함수
    function isalpha(c){
        return (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')));
    }
    
    // 알파벳을 체크해 알파벳으로만 이루어진 쌍을 만들고 배열에 담아주는 함수
    function checkAlpha(string){
        let arr = []
        for(let i = 0; i < string.length - 1; i++){
            if(isalpha(string[i]) && isalpha(string[i+1])){
                arr.push(string[i].toUpperCase() + string[i+1].toUpperCase());
            }
        }
        return arr;
    }
   
    let arr1 = checkAlpha(str1);
    let arr2 = checkAlpha(str2);
    let setArr1 = [...new Set(arr1)];	//중복제거
    let setArr2 = [...new Set(arr2)];	//중복제거
    let kyo = 0;
    let hap = 0;
    
    for(let i of setArr1){
        if(arr2.includes(i) === true){	//중복제거한 arr1의 값이 arr2에도 존재하는지 확인 
            kyo += Math.min(arr1.filter(el => el === i).length, arr2.filter(el => el === i).length);
            hap += Math.max(arr1.filter(el => el === i).length, arr2.filter(el => el === i).length);
        } else {	//원소가 겹치치 않는 경우(arr1)
            hap += arr1.filter(el => el === i).length;
        }
    }
    for(let j of setArr2){	//원소가 겹치치 않는 경우(arr2)
        if(arr1.includes(j) === false){
            hap += arr2.filter(el => el === j).length;
        }
    }    
    return hap === 0 ? 65536 : parseInt(kyo/hap * 65536);
}

 

 

다른 풀이 방법

function solution (str1, str2) {
  function explode(text) {
    const result = [];
    for (let i = 0; i < text.length - 1; i++) {
      const node = text.substr(i, 2);	// i번째 인덱스부터 2개씩 문자열 슬라이싱
      if (node.match(/[A-Za-z]{2}/)) {	// 알파벳인지 확인
        result.push(node.toLowerCase());	// 소문자로 변환해 result 배열에 추가
      }
    }
    return result;
  }

  const arr1 = explode(str1);
  const arr2 = explode(str2);
  const set = new Set([...arr1, ...arr2]);	// 중복제거
  let union = 0;
  let intersection = 0;

  set.forEach(item => {
    const has1 = arr1.filter(x => x === item).length;	// arr1 안의 set요소 길이 체크
    const has2 = arr2.filter(x => x === item).length;	// arr2 안의 set요소 길이 체크
    union += Math.max(has1, has2);
    intersection += Math.min(has1, has2);
  })
  return union === 0 ? 65536 : Math.floor(intersection / union * 65536);
}

💡 substr()

문자열에서 특정 위치에서 시작하여 특정 문자 수 만큼의 문자들을 반환하는 메서드

str.substr(start[, length])
  • start: 추출하고자 하는 문자들의 시작 위치
  • length: 추출할 문자들의 총 갯수
반응형