사용 언어: python 3.9.5
https://programmers.co.kr/learn/courses/30/lessons/17677
level2
전처리
모두 소문자로 바꾸기
특수문자, 공백, 숫자는 '0'으로 바꾸기
두 리스트가 모두 공집합일 때, 어느 한 리스트라도 공집합일 때 처리하기
모두 공집합 : 65536 반환
하나라도 공집합 : 0 반환(교집합이 항상 0이므로)
중복이 허용된 교집합 원소 수 구하기
일단 중복없는 교집합 구하기
ex) [1,2,3,3,3,4,5] 와 [3,3,4,5,5,6,7] 라면 [3,4,5]를 구함
구한 교집합 원소를 하나씩 각각의 리스트에서 몇 개 있는지 구해서 더 적은 개수 더해가기
ex) 교집합 [3,4,5]에서 3이 각각 몇개씩 있는지 구하고, 더 적은 개수를 택한다.
첫번째 리스트에는 3이 3개 있고 두번째 리스트에서는 3이 2개 있으므로 교집합 개수는 2다.
다음으로 4는 첫번째 리스트에 1개, 두번째 리스트에 1개 있으므로 현재까지 교집합 개수는 2+1= 3이다.
5는 첫번째 리스트에 1개, 두번째 리스트에 2개 있으므로 교집합 개수는 3+1=4가 된다.
중복이 허용된 합집합 원소 수 구하기(중복 허용)
두 리스트의 원소의 합을 구한 뒤 교집합 수를 빼면 합집합 원소의 개수가 된다.
import re
def change(str):
return re.sub('[^a-z]', '0', str.lower())
def set2(str):
list1 = []
for i in range(len(str)-1):
if '0' not in str[i:i+2]:
list1.append(str[i:i+2])
return list1
def solution(str1, str2):
# 전처리 : 모두 소문자로, 특수/숫자/공백은 숫자 0으로
str1 = change(str1)
str2 = change(str2)
# 0을 포함하지 않도록 2개씩 원소 묶기
list1 = set2(str1)
list2 = set2(str2)
if (not list1) and (not list2):
return 65536
if (not list1) or (not list2):
return 0
# 교집합
inter_cnt = 0
inter = set(list1).intersection(set(list2))
for i in inter:
inter_cnt += min(list1.count(i), list2.count(i))
# 합집합
union_cnt = len(list1) + len(list2) - inter_cnt
return int(inter_cnt/union_cnt * 65536)
성공
60분
소문자만 있는 문자열로 만들기 :
import re
# re.sub('소문자를 제외한 문자들', '0으로 바꾼다', 타겟 문자열 )
re.sub('[^a-z]', '0', str.lower())
교집합 구하기 : set3 = set1.intersection{set2)
합집합 구하기 : set3 = set1.union(set2)