[プログラマー]候補鍵(2019 KAKAO BLIND RECRUITMENT)


https://programmers.co.kr/learn/courses/30/lessons/42890

問題の説明は次のとおりです。


  • リレーショナル・データベースでは、「relation」のエンティティを識別できる唯一の属性(Attribute)または属性のセットで、次の2つの性質を満たすものを候補キー(Candidate Key)と呼びます.
  • 一意性(一意性):バージョン内のすべてのインスタンスについて、一意に識別する必要があります.
  • 最小性(minimality):一意性鍵を構成する属性(Attribute)の1つを除外すると、一意性が破壊されることを示す.すなわち、バージョン内のすべてのインスタンスを一意に識別するために必要な属性のみから構成されます.

  • 候補鍵の最大個数を求める.


  • 上記の例では、学生の個人情報バージョンでは、学生ごとに独自の「学号」があります.したがって、「学号」はバージョンの候補鍵になることができる.
    「名前」に同じ名前(「apeach」)を使用する学生がいるため、「名前」は候補鍵として使用できません.ただし、[名前](Name)と[プロフェッショナル](Professional)を同時に使用すると、バージョン内のすべての凡例が一意に認識されるため、候補鍵として使用できます.
    もちろん、「名前」、「専攻」、「学年」を併用しても、バージョン内のすべての凡例を一意に識別できますが、最小性を満たさないため、候補キーとして使用できません.
    したがって,以上の学生の個人情報の候補鍵は「学号」「氏名」「専攻」の2つである.
  • 理解できない場合は、リンクをクリックして説明を読むことができます.

    アルゴリズム#アルゴリズム#

  • を遡り、すべてのキーの組合せを求める.
  • キーの組み合わせでsetに対応するデータを入れます.
  • setのサイズがインスタンスの数に等しい場合、一意性が満たされる.一意性を満たすキーの組み合わせをsettempに入れます.
  • 3-1. setの要素にtempのサブセットがある場合、tempは最小性を満たしません.部分集合としての要素がない場合はset>にtempを追加します.
  • コード#コード#

    #include <string>
    #include <vector>
    #include <set>
    #include <iostream>
    using namespace std;
    bool setCompare(set<int> a,set<int> b){
        int temp=b.size();
        set <int> t=b;
        for(auto iter=a.begin();iter!=a.end();++iter)
            t.insert(*iter);
        return temp==t.size();
    }
    void BackTracking(set<set<int>>&a,vector<vector<string>>& relation,vector<int>&v,int& answer,int n,int cnt,int index=0){
        static bool visit[9]={false};
        if(v.size()==cnt){
            bool insertAble=true;
            set<string> s;
            set<int> temp;
            for(int i=0;i<relation.size();i++){
                string key="";
                for(int j=0;j<v.size();j++) key+=relation[i][v[j]]+"A";
                s.insert(key);
            }
            if(s.size()==relation.size()){
                for(int i:v) temp.insert(i);
                for(auto iter=a.begin();iter!=a.end();++iter){
                    if(setCompare(*iter,temp)){
                        insertAble=false;
                        break;
                    }
                }
                if(insertAble) {
                a.insert(temp);
                answer=max((int)a.size(),answer);}
            }
            return;
        }
        else{
            for(int i=index;i<n;i++){
                if(!visit[i]){
                    visit[i]=true;
                    v.push_back(i);
                    BackTracking(a,relation,v,answer,n,cnt,i+1);  
                    v.pop_back();
                    visit[i]=false;
                }
            }
        }
    }
    int solution(vector<vector<string>> relation) {
        int answer = 0; 
        set<set<int>> a;
        for(int i=1;i<=relation[0].size();i++){
            vector <int> v;
            BackTracking(a,relation,v,answer,relation[0].size(),i);}
        return answer;
    }