[ 프로그래머스 / PYTHON ] 후보키

yujeongkwon·2022년 7월 5일
0

프로그래머스 / PYTHON

목록 보기
42/77

문제 설명

관계 데이터베이스에서 릴레이션(Relation)의 튜플(Tuple)을 유일하게 식별할 수 있는 속성(Attribute) 또는 속성의 집합 중, 다음 두 성질을 만족하는 것을 후보 키(Candidate Key)라고 한다.
유일성(uniqueness) : 릴레이션에 있는 모든 튜플에 대해 유일하게 식별되어야 한다.
최소성(minimality) : 유일성을 가진 키를 구성하는 속성(Attribute) 중 하나라도 제외하는 경우 유일성이 깨지는 것을 의미한다. 즉, 릴레이션의 모든 튜플을 유일하게 식별하는 데 꼭 필요한 속성들로만 구성되어야 한다.
제이지를 위해, 아래와 같은 학생들의 인적사항이 주어졌을 때, 후보 키의 최대 개수를 구하라.

풀이 & comment

그냥 구현 문제

아니 11시부터 12시지나기 전까지 커밋할려고(1일 1커밋 목표 ^8^) 급하게 풀긴했는데
저 tp 배열, 즉 후보키의 속성별로 묶을려하는 저 한줄이 빠르게 안 떠올라서 굳이 굳이 돌아서 생각나는 대로 적으니까 시간이 더 걸린 것 같다. + (set.issubset() 함수도 몰라서 또 돌아가다 짜증나서 구글링 중 저 함수 찾음)
처음 보자마자 어떻게 풀어야할 지 눈에 보이니까 세세한 부분(한 행씩 후보키들의 속성별 묶어주기= 인덱스처럼 한번 헷갈리면 지구 끝까지 헷갈리는 것)을 길게 생각하지 않으니까 또 쓸데없는 시간을 날렸다. 어제도 이러지 말자 다짐했눈데 ㅎ0ㅎ..

22.10.04 다시품

그냥 구현 -> 조합활용
예전이랑 똑같네 쓸데없이 시간날리기 ㅎ,,
+)set.issubset() 함수 또 기억못함 ㅎㅎ
생각보다 쉬운편인데 왜 정답률이 39% 밖에 안되냐

❗오류

main함수
	for i in range(1,len(relation[0])+1): 
이 부분을 제대로 설정안해서 -0- 
	첫번째 오류
    열을 기준으로 하는거라 열이 개수인 len(relation[0])를 해줘야하는데
	relation[0]이 아니라 relation 써서 인덱스 오류 졸라뜸 -0-
	uniqueness이 함수에서 자꾸 인덱스 오류 떠서 엥 여기가 문젠가 하고 
    여기서 다시 디버깅해보느라 좀 걸렸음.

	두번째 오류 
	테케 5,6,8,21 이것들 틀렸으면 전체 행이 후보키일 때 경우를 안해준 거임.
	나 같은 경우 len(relation[0])+1)에서 +1 안해줌

내코드

처음 코드

from itertools import combinations
def dis(c,relation):
    cals = [[j[i] for j in relation] for i in c]
    set_ = []

    for i in range(len(relation)):
        temp = []
        for j in range(len(cals)):
            temp.append(cals[j][i])
        set_.append(tuple(temp))
    
    if len(set_) == len(set(set_)): return 1
    else:    return 0

def solution(relation):
    answer = []
    cal = [i for i in range(len(relation[0]))]

    for i in range(1,len(cal)+1):
        for c in combinations(cal,i):
            if len(answer) == 0:
                if dis(c,relation): answer.append(c)
            else:
                for li in answer:    
                    if set(li).issubset(c): break
                else:    
                    if dis(c,relation): answer.append(c)

    return len(answer)

다른 사람 본 후 코드 - 한번에 속성 묶어주기

from itertools import combinations
def dis(c,relation):
    cals = [[j[i] for j in relation] for i in c]
    set_ = [tuple(i[j] for j in c) for i in relation]
    if len(set_) == len(set(set_)): return 1
    else:    return 0

def solution(relation):
    answer = []
    cal = [i for i in range(len(relation[0]))]

    for i in range(1,len(cal)+1):
        for c in combinations(cal,i):
            if len(answer) == 0:
                if dis(c,relation): answer.append(c)
            else:
                for li in answer:    
                    if set(li).issubset(c): break
                else:    
                    if dis(c,relation): answer.append(c)

    return len(answer)

22.10.04 코드

from itertools import combinations

def minimality(combo,answer):
    for ans in answer:
        # x.issubset(y) -> x가 y의 서브set인가?
        if set(ans).issubset(combo): return 0
    else:   return 1


def uniqueness(relation, combo):
    set_ = {tuple(rel[c] for c in combo) for rel in relation}
    if len(relation) != len(set_):  return 0
    else:   return 1
    
    
def solution(relation):
    answer = []
    cal = [i for i in range(len(relation[0]))]
    for i in range(1,len(relation[0])+1):
        for c in combinations(cal,i):   
            #희소성 고려
            if minimality(c,answer) == 0:    continue
            #유일성 고려
            if uniqueness(relation, c) == 1: answer.append(c)
    return len(answer)
profile
인생 살자.

0개의 댓글