1问题描述
关系模型使用“关系”这种单一的数据结构,描绘出现实世界的实体及实体间的各种联系。对于一个关系模式来说,在理论上总有函数依赖存在,例如平凡函数依赖和候选键确定的函数依赖。函数依赖反映了属性间的关联性和数据的完整性约束。函数依赖是解决数据冗余的重要课题,一般总有一个作为问题展开的初始基础的函数依赖集F,为了找出其上的各种函数依赖。Armstrong公理系统是函数依赖的一个有效而完备的公理系统。
若要证明公理系统的完备性,就需要判定某个函数依赖是否属于某个特定的关系模式的函数依赖集F根据Armstrong推导出来的函数依赖的集合。因此,引入属性集的闭包的概念,将判定某个函数依赖是否逻辑蕴含于函数依赖集F的问题,转化为求解属性集闭包,并判断其被决定因素是否是该属性集闭包的子问题。
2算法设计
描述算法设计思想以及采用的主要数据结构。
2.1闭包的含义与计算
(1)定义:在关系模式R中为F所逻辑蕴含的函数依赖的全体叫作 F的闭包,记为F+
(2)计算 求属性集X关于函数依赖F的属性闭包X+。设关系模式R的全部属性集为U,在U上的函数依赖集为F,U的一个子集为X,计算X关于F的属性闭包X+。
具体实现如下:
(1)令X(0)=X,i=0
(2)求B,这里B = { A |($V)($W)(V→WÎF∧VÍX(i)∧AÎW)};
(3)X(i+1)=B∪X(i)
(4)判断X(i+1)= X(i)吗?
(5)若相等或X(i)=U ,则X(i)就是XF+ ,
算法终止。
(6)若否,则 i=i+l,返回第(2)步。
3算法实现
描述系统的运行环境、源代码等,应给出各模块对应的流程图
3.1运行环境
3.2源代码
#include
#include
//#include
#include
using namespace std;
string element;//待求闭包结果
voidInitializing(multimap &fun);//初始化输入
void ToUpper(string &str);//转换成大写字母
void Calculator(string&oldelement,multimap & fun);//计算结果
void Sort(string& str);//升序排序
void Combine(int len,int k,string&str,string &entry,int count,multimap& fun);//求组合结果
void Search(stringentry,multimap& fun);//查找函数依赖
void Erase(string& str);
//****************************************************************************
multimap end;//函数依赖闭包
void End(multimap&fun);//求F+闭包
void CombineEnd(int len,int k,string&str,string &entry,int count,multimap& fun);
void CombineBibao(int len,int k,string& str,string &entry,int count,string left);//保存函数依赖的映射
//主程序
int main()
{
multimapfun;//函数依赖映射
Initializing(fun);
stringoldelement;
cout<
cin>>oldelement;
ToUpper(oldelement);//转换成大写字母
while(oldelement != "END")
{
cout<
Calculator(oldelement,fun);//计算闭包
cout<
cout<
cin>>oldelement;
ToUpper(oldelement);
}
//计算函数依赖闭包
End(fun);
intcount =0;
cout<
for(multimap::iterator iter =end.begin();iter!=end.end();iter++)
{
cout<first<"<second<
count++;
}
cout<
}
//初始关系
void Initializing(multimap&fun)
{
stringleft,right;
pairentry;
intcount = 1;
cout<
<B。"
<
cin>>left;
ToUpper(left);//转换成大写字母
while(left!="END")
{
cin>>right;
ToUpper(right);//转换成大写字母
while(right=="END")
{
cout<
cin>>right;
ToUpper(right);
}
Sort(right);//升序排序
Erase(right);//去除重复元素
Sort(left);//升序排序
Erase(left);//去除重复元素
entry= make_pair(left,right);//做函数依赖left-->right的映射
fun.insert(entry);
cout<"<
cin>>left;
ToUpper(left);
}
cout<
}
//转换成大写字母
void ToUpper(string &str)
{
strings(str);
string::iteratoriter = s.begin();
str.clear();
for(iter= s.begin(); iter!=s.end();iter++)
{
charc = *iter;
c= c+'A'-'a';
str.push_back(c);
}
}
//升序排序
void Sort(string& str)
{
string::iteratoriter_i = str.begin();
string::iteratoriter_j = str.begin();
stringp,q;
unsignedint i,j;
for(i = 0;i
{
iter_j= iter_i ;
if(iter_i==str.end())
break;
iter_j++;
for(j = i+1;j
{
p= *iter_i;
q= *iter_j;
if(p>q)
{
str.replace(i,1,q);
str.replace(j,1,p);
}
if(iter_j==str.end())
break;
iter_j++;
}
iter_i++;
}
}
//计算结果
void Calculator(string&oldelement,multimap & fun)
{
Sort(oldelement);//升序排序
Erase(oldelement);//去除重复元素
element= oldelement;//保存当前属性集
stringentry;//取所有可能的属性集
do
{
oldelement= element;
for(unsigned int i = 1;i<=oldelement.length();i++)
{
entry.clear();
Combine(oldelement.length(),i,oldelement,entry,0,fun);//组合
}
}while(element!=oldelement);
}
//取所有可能的集合
void Combine(int len,int k,string&str,string &entry,int count,multimap& fun)
{
if(len== k)
{
while(k> 0)
{
entry.push_back(str.c_str()[k-1]);
k--;
}
Search(entry,fun);
return;
}
else
{
if(0== k)
{
Search(entry,fun);
return;
}
entry.push_back(str.c_str()[len-1]);
Combine(len-1,k-1,str,entry,count+1,fun);
if(count>0)
entry.erase(entry.length()-k,k);
else
entry.clear();
}
Combine(len-1,k,str,entry,count,fun);
}
//查询所存在的函数依赖
void Search(stringentry,multimap& fun)
{
Sort(entry);
multimap::iteratoriter = fun.find(entry);
while(iter!=fun.end())
{
if(iter->first == entry)
element.append(iter->second);
iter++;
}
Sort(element);
//去除重复元素
Erase(element);
}
//去除重复元素
void Erase(string& str)
{
unsignedint count = 1;
for(string::iterator i = str.begin();i!=str.end();i++,count++)
{
string::iteratorj = i;
j++;
if(j == str.end())
return;
if(*i == *j)
str.erase(count--,1);
}
}
//**************函数依赖闭包********************
//=======================================================
void End(multimap&fun)
{
stringmembers;//所有元素集合
for(multimap::iterator iter =fun.begin();iter!=fun.end();iter++)
{
members.append(iter->first);
members.append(iter->second);
}
stringentry;
//取所有可能的元素集
for(unsigned int i = 1;i<=members.length();i++)
{
entry.clear();
CombineEnd(members.length(),i,members,entry,0,fun);//组合
}
}
//取所有可能的集合
void CombineEnd(int len,int k,string&str,string &entry,int count,multimap& fun)
{
strings;
if(len== k)
{
while(k> 0)
{
entry.push_back(str.c_str()[k-1]);
k--;
}
//Sort(entry);
//Erase(entry);
s= entry;
Sort(s);
Erase(s);
Calculator(s,fun);//求其闭包
//entry的闭包element,做映射,存在end中
stringtemp;
for(unsigned int i = 1;i<=element.length();i++)
{
temp.clear();
CombineBibao(element.length(),i,element,temp,0,entry);//组合
}
return;
}
else
{
if(0== k)
{
//Sort(entry);
//Erase(entry);
s= entry;//保护entry
Sort(s);
Erase(s);
Calculator(s,fun);//求其闭包
//entry的闭包element,做映射,存在end中
stringtemp;
for(unsigned int i = 1;i<=element.length();i++)
{
temp.clear();
CombineBibao(element.length(),i,element,temp,0,entry);//组合
}
return;
}
entry.push_back(str.c_str()[len-1]);
CombineEnd(len-1,k-1,str,entry,count+1,fun);
if(count>0)
entry.erase(entry.length()-k,k);
else
entry.clear();
}
CombineEnd(len-1,k,str,entry,count,fun);
}
//保存函数依赖的闭包在end中
void CombineBibao(int len,int k,string& str,string &entry,int count,string left)
{
strings;
if(len== k)
{
while(k> 0)
{
entry.push_back(str.c_str()[k-1]);
k--;
}
s= entry;
Sort(s);
Erase(s);
Sort(left);
Erase(left);
//保存left->s的映射在end中
if(!entry.empty())
{
multimap::iteratoriter;
for(iter =end.begin();iter!=end.end();iter++)
{
if(iter->first == left && iter->second == s)
break;
}
if(iter==end.end())
end.insert(make_pair(left,s));
}
return;
}
else
{
if(0== k)
{
//Sort(entry);
//Erase(entry);
s= entry;
Sort(s);
Erase(s);
Sort(left);
Erase(left);
//保存left->s的映射在end中
if(!entry.empty())
{
multimap::iteratoriter;
for(iter =end.begin();iter!=end.end();iter++)
{
if(iter->first == left && iter->second == s)
break;
}
if(iter==end.end())
end.insert(make_pair(left,s));
}
return;
}
entry.push_back(str.c_str()[len-1]);
CombineBibao(len-1,k-1,str,entry,count+1,left);
if(count>0)
entry.erase(entry.length()-k,k);
else
entry.clear();
}
CombineBibao(len-1,k,str,entry,count,left);
}