具有无损连接性的BCNF分解 C++实现
2014-11-27 11:12
183 查看
------------------------------------------------------------------------------------
欢迎转载,请附上链接
http://blog.csdn.net/iemyxie/article/details/41543169
-----------------------------------------------------------------------------------
何为BC范式?
BCNF是3NF基础上的一种特殊情况,每个属性不传递依赖于R的候选键(包含关系),即每个表中只有一个候选键。
算法伪代码
输入:关系模式R以及R上的函数依赖集F
输出:R的BCNF分解Result,它关于F具有无损连接性
方法:
Result = {R}
while(存在Ri包含于Result,但Ri不是BCNF)
begin
找出Ri中满足如下条件的非平凡的函数依赖:X->Y包含于Fi的闭包,且X不是Ri的超码
Result = Result -
{Ri} ∪{XY,Ri - Y}
end
return Result
算法C++实现(算法主体来自@DarkSword)
Updated on:2014-12-10
欢迎转载,请附上链接
http://blog.csdn.net/iemyxie/article/details/41543169
-----------------------------------------------------------------------------------
何为BC范式?
BCNF是3NF基础上的一种特殊情况,每个属性不传递依赖于R的候选键(包含关系),即每个表中只有一个候选键。
算法伪代码
输入:关系模式R以及R上的函数依赖集F
输出:R的BCNF分解Result,它关于F具有无损连接性
方法:
Result = {R}
while(存在Ri包含于Result,但Ri不是BCNF)
begin
找出Ri中满足如下条件的非平凡的函数依赖:X->Y包含于Fi的闭包,且X不是Ri的超码
Result = Result -
{Ri} ∪{XY,Ri - Y}
end
return Result
算法C++实现(算法主体来自@DarkSword)
#include<iostream> #include<string> #include<algorithm> #include<vector> #include<stdio.h> using namespace std; string R; //关系模式 vector< pair<string,string> > F; // 函数依赖集(FD) vector<string>subset; //关系模式 R 的所有子集 char *temp; //求所有子集的辅助变量 vector<string>candidate_key; // 所有的候选键 vector<string>super_key; //所有的超键 /*********************************************************************/ bool _includes(string s1,string s2){ //判断 s2 的每个元素是否都存在于 s1 sort(s1.begin(),s1.end()); sort(s2.begin(),s2.end()); return includes(s1.begin(),s1.end(),s2.begin(),s2.end()); // includes函数是基于有序集合的,所以先排序 } string get_attribute_closure(const string &X, const vector< pair<string,string> > &F){ //返回属性集X的闭包 string ans(X); //初始化 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] && _includes(ans,F[i].first) ){ vis[i]=1; ans += F[i].second; } } }while(temp!=ans); // ans 无任何改变时终止循环 delete []vis; vis=NULL; //删掉重复的 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){ // 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){ //求关系模式R的所有子集,保存在subset中 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){ //判断 s 是否是候选键 for(int i=0;i!=candidate_key.size();++i) if(_includes(s,candidate_key[i])) //如果s包含了已知的候选键,那么s就不是候选键 return false; return true; } bool cmp_length(const string &s1,const string &s2){ //对 subset 以字符串长度排序 return s1.length()<s2.length(); } void get_candidate_key(const string &R, const vector< pair<string,string> > &F){//求关系模式 R基于F的所有候选键 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){ //返回 F 的依赖集 vpss G(F); //使 G 中每个 FD 的右边均为单属性 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]; //在 G 的每个 FD 中消除左边冗余的属性 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){ //对于第i个FD,判断是否可消除first的第j个属性 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; //必须先去重 sort(G.begin(),G.end()); G.erase( unique(G.begin(),G.end()),G.end()); //在 G 中消除冗余的 FD vpss ans; for(int i=0;i!=G.size();++i){ //判断第i个 FD 是否冗余 vpss temp(G); temp.erase(temp.begin()+i); if( ! _includes(get_attribute_closure(G[i].first,temp),G[i].second) ) //第 i 个 FD 不是冗余 ans.push_back(G[i]); } return ans; } string _difference(string a,string b){ //先去重,再返回 a 和 b 的差集,即 a-b string c; c.resize(a.size()); sort(a.begin(),a.end()); a.erase( unique(a.begin(),a.end()),a.end()); sort(b.begin(),b.end()); string::iterator It=set_difference(a.begin(),a.end(),b.begin(),b.end(),c.begin()); c.erase(It,c.end()); return c; } /***************将关系模式 R 无损分解成 BCNF 模式集 Update on 2014.12.10*****************/ <span style="color:#ff6600;">vector<string> split_to_bcnf(const string &R, const vector< pair<string,string> > &F){ string ans = R; <pre name="code" class="cpp"><span style="white-space:pre"> </span>string temp; string tempf; vector<string> result; int i; string bibao; string key=""; vector< pair<string,string> > FF = F; int flag=0; while(1) { temp = ans; bibao = get_attribute_closure(ans,FF); get_candidate_key(ans,FF); for(int q=0;q!=candidate_key.size();q++){ key+=candidate_key[q]; } for(i=0;i!=FF.size();i++){ tempf=FF[i].first+FF[i].second; if(_includes(ans,tempf)){ flag=1; } if( _includes(bibao,tempf) && (! _includes(FF[i].first,key))) { result.push_back(FF[i].first+FF[i].second); ans=_difference(ans,FF[i].second); } } if(i== FF.size() && temp == ans) { if(flag==0){ ans=""; } if( ! (ans=="")){ result.push_back(ans); } break; } flag=0; } sort(result.begin(),result.end()); result.erase( unique(result.begin(),result.end()),result.end()); return result; }
<pre name="code" class="cpp">void init(){ //初始化 R=""; F.clear(); } void inputR(){ //输入关系模式 R // cout<<"请输入关系模式 R:"<<endl; cin>>R; } void inputF(){ //输入函数依赖集 F int n; string temp; // cout<<"请输入函数依赖的数目:"<<endl; cin>>n; // cout<<"请输入"<<n<<"个函数依赖:(输入形式为 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){ //读入 ps.first if(temp[j]!='-'){ if(temp[j]=='>') break; ps.first+=temp[j]; } } ps.second.assign(temp,j+1,string::npos); //读入 ps.second F.push_back(ps); //读入ps } } /**************************************************************************/ int main(){ freopen("in.txt","r",stdin); init(); inputR(); inputF(); string anss; string f; vector<string> ans=split_to_bcnf(R,F); for(int qqq=0;qqq!=ans.size();qqq++){ cout<<ans[qqq]<<endl; } return 0; }PS:用DEV运行,不要用VC。前文已经说过原因,不再赘述。
Updated on:2014-12-10
相关文章推荐
- 具有无损性连接和保持函数依赖的3NF分解C++实现
- 四、转换成BCNF的保持无损连接的分解
- 24位真彩图转8位灰度图并分解位平面 c-c++实现
- 矩阵奇异值分解简介及C++/OpenCV/Eigen的三种实现
- 判别一个分解的无损连接性
- 转换成BCNF的保持无损连接的分解
- 3.转换成BCNF的保持无损连接的分解
- 24位真彩图分离三通道以及分解位平面 c-c++实现
- 推荐系统之矩阵分解及C++实现
- 【数据库】转换成BCNF的保持无损连接的分解
- 矩阵特征分解介绍及雅克比(Jacobi)方法实现特征值和特征向量的求解(C++/OpenCV/Eigen)
- 模式分解---无损连接性的判断方法(转)
- 模式分解的无损连接性之深入剖析
- 从QR分解到PCA,再到人脸识别(c++实现)
- C++实现控制台输出具有颜色类
- C++实现具有基本功能的智能指针
- 编程珠玑第六章习题二——C++实现一个数的因子分解
- C++实现的大整数分解Pollard's rho算法程序
- 一、判别一个分解的无损连接性
- 转换成BCNF的保持无损连接的分解