[プログラマ/42890]候補鍵(Java)


Question

  • 問題リンク:https://programmers.co.kr/learn/courses/30/lessons/428902
  • 分類:完全ナビゲーション(ブルートフォード)
  • 解答時間:120分
  • 問題の説明

  • の複数のコラムから候補鍵を選びたいです.
  • 候補鍵一意識別子row:一意性
  • を使用する必要があります.
  • は、一意の識別可能な値の組合せの中で最小の組合せである必要がある:最小
  • .
  • 候補鍵の個数は?
  • Solution


    プールアクセス方法

  • すべての色の組み合わせを求める
  • 組合せにおける一意性に満足する組合せ選択
  • は、最小性を満たす組合せのみを格納する
  • は、これまでに出現する候補鍵の組合せを含まない組合せ
  • のみを保持する.

    正しいコード

    package com.programmers.bp;
    
    import java.util.HashSet;
    
    public class CandidateKey {
      static int rows, columns;
      static String[][] table;
      static HashSet<HashSet<Integer>> candidate;
    
      public int solution(String[][] relation) {
        rows = relation.length;
        columns = relation[0].length;
        table = relation;
        candidate = new HashSet<HashSet<Integer>>();
    
        for (int pick = 1; pick <= columns; pick++) {
          getKeySet(0, pick, new HashSet<Integer>());
        }
    
        return candidate.size();
      }
    
      /**
       * 키의 조합을 구하는 함수
       * start : 키 집합 안에 넣을 다음 값
       * pick : 뽑아야할 개수
       * set : 뽑은 컬럽 조합 집합
       **/
      public void getKeySet(int start, int pick, HashSet<Integer> set) {
        if (pick == 0) {
    
          // 유일성을 만족하지 않으면 후보키 될 수 없음
          if (!isUnique(set))
            return;
    
          // 이미 뽑힌 후보키에서 최소성 확인
          for (HashSet<Integer> part : candidate) {
            HashSet<Integer> temp = new HashSet<>(part);
            
            // 기존의 후보키 조합 - 뽑힌 후보키 조합
            temp.removeAll(set);
    
            // = 0
            // 뽑힌 후보키 조합이 기존의 조합을 포함하고 있음
            if (temp.size() == 0)
              return;
          }
    
          candidate.add(set);
    
          return;
        }
    
        for (int i = start; i < columns; i++) {
          HashSet<Integer> newSet = new HashSet<Integer>(set);
          newSet.add(i);
          getKeySet(i + 1, pick - 1, newSet);
        }
      }
    
      /**
       * 키의 조합이 유일성을 만족하는지 확인하는 함수
       **/
      public boolean isUnique(HashSet<Integer> set) {
        HashSet<String> setResult = new HashSet<String>();
    
        for (String[] row : table) {
          String value = "";
    
          for (Integer idx : set) {
            value += row[idx];
          }
          
          // 겹치는 값이 하나라도 있으면 값들을 유일하게 식별해낼 수 없음
          if (!setResult.add(value))
            return false;
        }
    
        return true;
      }
    }
    

    卵。掃く。油。方法(知っていれば役に立つ方法)


    集約演算方法
    HashSet<T> hashSet = new HashSet<T>();
    
    hashSet.addAll(set1);	// 합집합 : set1에 들어있는 값 다 hashSet에 넣음
    hashSet.removeAll(set2);	// 차집합 : set2에 들어있는 값 다 hashSet에서 삭제
    hashSet.retainAll(set3);	// 교집합 : set과 set3와 공통된 부분만 남김