BCNF with lossless connectivity implements C ++ decomposition and does not damage bcnf
Bytes ---------------------------------------------------------------------------------------------------------
This article welcomes reprint, reprint Please attach link http://blog.csdn.net/iemyxie/article/details/41543169
Bytes ---------------------------------------------------------------------------------------------------------
What is the BC paradigm?
BCNF is a special case based on 3NF. Each attribute does not pass a candidate key (including relation) dependent on R, that is, each table has only one candidate key.
Algorithm pseudocode
Input: relational mode R and function dependency set F on R
Output: R's BCNF decomposition Result, which indicates that F has lossless connectivity.
Method:
Result = {R}
While (Ri is included in Result, but Ri is not BCNF)
Begin
Find out the non-trivial function dependency that satisfies the following conditions in Ri: X-> Y contains the Fi closure, and X is not the supercode of Ri.
Result = Result-{Ri} else {XY, Ri-Y}
End
Return Result
Algorithm C ++ implementation (algorithm subject comes from @ DarkSword)
# Include <iostream> # include <string> # include <algorithm> # include <vector> # include <stdio. h> using namespace std; string R; // link mode vector <pair <string, string> F; // function dependency set (FD) vector <string> subset; // all subsets of relational mode R char * temp; // evaluate the auxiliary variable vector of all subsets <string> candidate_key; // all candidate keys vector <string> super_key; // all the superkeys /********************************* * **********************************/bool _ des (string s1, string S2) {// determine whether each element of s2 exists in s1 sort (s1.begin (), s1.end (); sort (s2.begin (), s2.end ()); return vertex des (s1.begin (), s1.end (), s2.begin (), s2.end (); // The vertex des function is based on an ordered set, so first sort} string get_attribute_closure (const string & X, const vector <pair <string, string >>& F) {// return the closure string ans (X) of attribute set X ); // initialize ans string temp; bool * vis = new bool [F. size ()]; fill (vis, vis + F. size (), 0); do {temp = ans; for (int I = 0; I! = F. size (); ++ I) {if (! Vis [I] & _ pair des (ans, F [I]. first) {vis [I] = 1; ans + = F [I]. second ;}}while (temp! = Ans); // terminate the loop delete [] vis; vis = NULL if ans does not change any; // delete the repeated sort (ans. begin (), ans. end (); ans. erase (unique (ans. begin (), ans. end (), ans. end (); return ans;} void _ all_subset (int pos, int cnt, int num) {// auxiliary function of get_all_subset () if (num <= 0) {temp [cnt] = '\ 0'; subset. push_back (temp); return;} temp [cnt] = R [pos]; _ all_subset (pos + 1, cnt + 1, num-1); _ all_subset (pos + 1, cnt, num-1);} void get_all_subset (const string & R ){ // Evaluate all subsets of relational mode R and save them in subset. clear (); temp = NULL; temp = new char [R. size ()]; _ all_subset (0, 0, R. length (); delete [] temp; temp = NULL;} bool is_candidate_key (const string & s) {// determine if s is a candidate key for (int I = 0; I! = Candidate_key.size (); ++ I) if (_ includes (s, candidate_key [I]) // if s contains a known candidate key, s is not the candidate key return false; return true;} bool cmp_length (const string & s1, const string & s2) {// return s1.length () <s2.length ();} void get_candidate_key (const string & R, const vector <pair <string, string> & F) {// evaluate relational mode R all F-based candidate keys get_all_subset (R); sort (subset. begin (), subset. end (), cmp_length); candidate_key.clear (); Super_key.clear (); for (int I = 0; I! = Subset. size (); ++ I) {if (_ includes (get_attribute_closure (subset [I], F), R) {super_key.push_back (subset [I]); if (is_candidate_key (subset [I]) candidate_key.push_back (subset [I]) ;}} typedef vector <pair <string, string> vpss; vpss get_minimum_rely (const vpss & F) {// return the dependency set vpss G (F) of F ); // make the right side of each FD in G a single property for (int I = 0; I! = G. size (); ++ I) {if (G [I]. second. length ()> 1) {string f = G [I]. first, s = G [I]. second, temp; G [I]. second = s [0]; for (int j = 1; j <s. length (); ++ j) {temp = s [j]; G. push_back (make_pair (f, temp) ;}} int MAXN = 0; for (int I = 0; I! = G. size (); ++ I) if (G [I]. first. length ()> MAXN) MAXN = G [I]. first. length (); bool * del = new bool [MAXN]; // remove the left-side redundancy attribute in each FD of G for (int I = 0; I! = G. size (); ++ I) {if (G [I]. first. length ()> 1) {fill (del, del + G [I]. first. length (), 0); for (int j = 0; j! = G [I]. first. length (); ++ j) {// for the I-th FD, determine whether the j-th attribute of first can be eliminated; string temp; del [j] = 1; for (int k = 0; k! = G [I]. first. length (); ++ k) if (! Del [k]) temp + = G [I]. first [k]; if (! _ Includes (get_attribute_closure (temp, G), G [I]. second) // del [j] = 0;} string temp; for (int j = 0; j! = G [I]. first. length (); ++ j) if (! Del [j]) temp + = G [I]. first [j]; G [I]. first = temp ;}} delete [] del; del = NULL; // The sort (G. begin (), G. end (); G. erase (unique (G. begin (), G. end (), G. end (); // eliminate redundant FD vpss ans in G; for (int I = 0; I! = G. size (); ++ I) {// determine whether the I-th FD is redundant vpss temp (G); temp. erase (temp. begin () + I); if (! _ Includes (get_attribute_closure (G [I]. first, temp), G [I]. second) // The I FD is not redundant ans. push_back (G [I]);} return ans;} string _ difference (string a, string B) {// returns the difference set between a and B, that is, a-B string c; c. resize (. size (); sort (. begin (),. end ();. erase (unique (. begin (),. end (),. end (); sort (B. begin (), B. end (); string: iterator It = set_difference (. begin (),. end (), B. begin (), B. end (), c. begin (); c. erase (It, c. End (); return c ;} /************** lossless decomposition of relational mode R into BCNF mode set ************** * **/vector <string> split_to_bcnf (const string & R, const vector <pair <string, string> & F) {vector <string> ans; vector <string> temp; ans. push_back (R); vector <pair <string, string> FF = get_minimum_rely (F); // Save the minimum dependency set of F to FF int flag; do {flag = 0; temp. resize (ans. size (); temp. assign (ans. begin (), ans. end (); // Save the current ans for (int I = 0; I! = Ans. size (); ++ I) {vector <pair <string, string> MC; // calculates the minimum dependent set for (int j = 0; j! = FF. size (); ++ j) {if (_ des (ans [I], FF [j]. first) & _ regiondes (ans [I], FF [j]. second) MC. push_back (FF [j]);} sort (MC. begin (), MC. end (); MC. erase (unique (MC. begin (), MC. end (), MC. end (); get_candidate_key (ans [I], MC); for (int j = 0; j! = MC. size (); ++ j) {int is_super_key = 0; for (int k = 0; k! = Super_key.size (); ++ k) {if (_ pair des (MC [j]. first, super_key [k]) {is_super_key = 1; break;} // an extraordinary FD x-> y exists in ans [I, if x does not contain a superkey, the ans [I] // is decomposed into xy and ans [I]-y; if (! Is_super_key) {ans. push_back (_ difference (ans [I], MC [j]. second); ans [I] = MC [j]. first + MC [j]. second; flag = 1; break;} if (flag) break;}/******** when the ans do not change, terminate the cycle, otherwise, the endless loop **********/sort (temp. begin (), temp. end (); sort (ans. begin (), ans. end (); temp. erase (unique (temp. begin (), temp. end (), temp. end (); ans. erase (unique (ans. begin (), ans. end (), ans. end (); if (equal (ans. begin (), ans. end (), temp. begin ()) Break;} while (flag); return ans ;} /*************************************** * ****************************/void init () {// initialize R = ""; F. clear ();} void inputR () {// enter the relational mode R cout <"Enter the relational mode R:" <endl; cin> R ;} void inputF () {// input function dependency set F int n; string temp; cout <"Enter the number of function dependencies:" <endl; cin> n; cout <"enter" <n <"function dependencies: (the input format is a-> B AB-> c)" <endl; for (int I = 0; I <n; ++ I) {pair <string, string> ps; cin> temp; int j; For (j = 0; j! = Temp. length (); ++ j) {// read ps. first if (temp [j]! = '-') {If (temp [j] = '>') break; ps. first + = temp [j] ;}} ps. second. assign (temp, j + 1, string: npos); // read ps. second F. push_back (ps ); // read ps }}/********************************* **************************************** */int main () {freopen ("in.txt", "r", stdin); init (); inputR (); inputF (); vector <string> ans = split_to_bcnf (R, F ); cout <"lossless decomposition of relational mode R into BCNF mode sets, as follows:" <endl; for (int I = 0; I! = Ans. size (); ++ I) cout <ans [I] <endl; return 0 ;}
PS: Run with DEV. Do not use VC. I have already said the reason and will not go into details.
Attached test data:
Input sample
Abc
2
A-> B
Bc->
Abcdef
4
AB-> ef
D-> e
E-> f
Cd-> ef
Abcdef
2
AB-> cd
Bc-> ef
Abcdef
4
AB-> ef
C-> d
D-> e
Bc-> de
Output sample
AB
Ac
Abe
Abcdf
Bce
Bcf
Abcd
Abc
Abe
Abf
C
Cd
Bytes -------------------------------------------------------------------------------------------------------------
This article welcomes reprint, reprint Please attach link http://blog.csdn.net/iemyxie/article/details/41543169
Bytes -------------------------------------------------------------------------------------------------------------