문제 확인

 

프로그래머스

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

programmers.co.kr

나의 풀이

  • 처음 풀 때는 문제 조건을 제대로 확인하지 않아, 특수 문자 / 공백을 제거해서 풀었다.
    • 이 경우 aa1+aa2와 AAAA12가 동일해지는 문제가 생긴다.
  • 특수 문자 / 공백을 미리 제거 하면 문제가 생기기 때문에, 알파벳 여부를 원소를 만들 때 확인했다. 
# 자카드 유사도 : (두 집합의 교집합 크기 / 두 집합의 합집합 크기
# 중복 문자에 대해서도 처리 가능
# 둘다 공집합인 경우 -> 1로 정의
from collections import Counter

def solution(str1, str2):
    # 공집합일 경우 생각해서 1로 초기화
    j_sim = 1
    # 소문자로 변경
    str1, str2 = str1.lower(), str2.lower()
    # 원소 만들기
    str1 = [str1[i:i + 2] for i in range(len(str1) - 1) if str1[i].isalpha() and str1[i + 1].isalpha()]
    str2 = [str2[i:i + 2] for i in range(len(str2) - 1) if str2[i].isalpha() and str2[i + 1].isalpha()]
    # 원소 개수 세기
    str1 = Counter(str1)
    str2 = Counter(str2)
    # 분모, 분자 원소 구하기
    divisor = set(str1.keys()) | set(str2.keys())
    dividend = set(str1.keys()) & set(str2.keys())
    # 분모, 분자 값 결정하기
    divisor = sum([max(str1[i], str2[i]) for i in divisor])
    dividend = sum([min(str1[i], str2[i]) for i in dividend])
    if divisor != 0:
        j_sim = dividend / divisor
    # 결과 조건에 맞도록
    j_sim *= 65536
    j_sim = int(j_sim)
    
    return j_sim

다른 사람 풀이

  • str.isalpha() : 각 문자에 적용되지 않고, 전체 문자열에 적용 됨
  • Counter로도 Boolean 연산을 할 수 있음
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

출처

 

프로그래머스

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

programmers.co.kr