求某属性集的函数依赖集的闭包运算

闲的没事干,看了看数据库的求闭包的。顺便将代码页实现了。如果有错请指出。

#include<iostream>
#include<string>
#include<bitset>
#include<string.h>
#include<map>
#define ELE  26   //U 属性集合  最多为26个
#define R     50    //输入的F的函数依赖集的元素个数最多为50 个
using namespace std;


int match[R][ELE]={-1};
bitset<26>    b[R];          //
bitset<26>   unit;//    集合
bitset<26>   X;//表示当前的属性集合
int used[R]={0};//表示F函数依赖集的每一个函数依赖是否已经用过
int t;  

int  main()
{
  int i,j,k,flag;
  int num,ele;
  string str;
  cout<<"**************闭包的计算************************************\n";
  cout<<"输入属性几个的个数:<只用输入个数,系统会自动生成ABC......Z>\n";
  cin>>ele;
  cout<<"系统生成的属性集合是:\n";
  for(j=0;j<ele;j++)
  {
   cout<<""<<(char)(j+'A')<<"\t";
   unit[j]=1; 
  }
cout<<endl<<unit;
cout<<"\n请输入F函数依赖集的大小:\n";
cin>>num;
cin.get();
cout<<"请输入函数依赖 <like AB->C>\n";
for(i=0;i<num;i++)
{
 str="";
 getline(cin,str);     //假设输入的都是正确的值
 j=str.length();
 k=0;
  flag=0;
 while(str[k]!='\0')
 {
    if((str[k]>='a'&&str[k]<='z')||(str[k]<='Z'&&str[k]>='A'))
    {
     t=(str[k]-'a'>=0)?(str[k]-'a'):(str[k]-'A');
     if(flag==0)
     match[i][t]=1;        //依赖函数x->y  的x部分
     else                 
      b[i][t]=1;            //依赖函数的x->y  的y部分
    }
    else    //遇到—>的时候
     flag=1;
    ++k;
 
 }
   


}
cin.get();                               //*****************************
str="";
cout<<"请输入要计算的属性集:\n";
getline(cin,str);
k=str.length();

for(i=0;i<k;i++)
{
    t=(str[i]-'a'>=0)?(str[i]-'a'):(str[i]-'A');

 X[t]=1;

}
cout<<"********************闭包计算结果**************************\n";
cout<<"属性集{"<<str<<"}"<<"在集合{";
for(i=0;i<ele-1;i++)
cout<<(char)(i+'A')<<",";
cout<<(char)((ele-1)+'A')<<"}的关于F函数依赖的闭包是:{";

flag=0;
bitset<26>   temp;
while(!flag)
{

 if(unit==X||X==temp)
 {
  flag=1;
  continue;
 }
 if(temp!=0)
 X=temp;
 else
  temp=X;
for(i=0;i<num;i++)   //每次从头开始扫描F

{
 if(!used[i])
 {
 
    for(j=0;j<ele;++j)
 {
  if(match[i][j]==0||(match[i][j]==1&&X[j]==1))
     continue;
  else
   break;
 
 }// # end for
  if(j>=ele)
  {
     used[i]=1;
  for(int loop=0;loop<ele;loop++)    //进行异或操作
   temp[loop]=b[i][loop]?1:temp[loop];
 
  }
 }
//#  end if


}//# end for

 


}


 
for(j=0;j<ele-1;j++)
if(X[j]==1)
   cout<<(char)(j+'A')<<",";
if(X[ele-1]==1)
cout<<(char)((ele-1)+'A')<<"}\n";


}
 
/*
AB->C
B->D
C->E
EC->B
AC->B
*/

 

### 函数依赖的概念及其在数据库中的表示 函数依赖是一种用于描述关系数据库中属性之间逻辑约束的形式化工具。在一个给定的关系模式 \( R(U) \),其中 \( U \) 是一组属性,如果对于任意两个元组 \( t_1, t_2 ∈ r(R) \),满足条件 \( t_1[X] = t_2[X] ⇒ t_1[Y] = t_2[Y] \),则称 \( X → Y \) 成立,这里 \( X ⊆ U \) 和 \( Y ⊆ U \)[^1]。 #### 如何表示函数依赖函数依赖通常以合形式表示为 \( F = \{X_i → Y_i\} \),其中每个 \( X_i → Y_i \) 表示一个具体的函数依赖关系。例如,在引用[3]的例子中,\( F = \{A→C, C→A, B→AC, D→AC, BD→A\} \) 就是一个函数依赖[^3]。 --- ### 计算最小函数依赖的过程 为了减少冗余并优化存储结构,常常需要函数依赖的 **最小覆盖** 或称为 **最小函数依赖**。其目标是通过消除多余的依赖项和多余属性来简化原始函数依赖 \( F \)。 以下是计算过程的核心原则: 1. **分解规则的应用**: 如果某个函数依赖 \( A → BC \) 存在于 \( F \) 中,则可以将其拆分为多个更简单的依赖,如 \( A → B \) 和 \( A → C \)[^2]。 2. **去除冗余依赖**: 对于每一个函数依赖 \( X → Y \in F \),验证是否可以从剩余部分推导出该依赖。如果是,则说明此依赖是冗余的,可移除。 3. **精简左侧属性**: 针对每条形如 \( XY → Z \) 的依赖,尝试逐一去掉左边某些属性 (比如 \( X \)) 后重新测试闭包运算结果是否会改变;若不影响最终结论,则表明这些额外属性也是不必要的。 基于上述方法论,我们能够逐步构建起既简洁又完整的最小函数依赖表达方式。 ```python def compute_minimal_cover(F): minimal_cover = [] # Step 1: Decompose each FD into single attribute on the RHS. decomposed_F = set() for fd in F: lhs, rhs = fd.split('->') for attr in rhs.strip(): decomposed_F.add(f"{lhs.strip()}->{attr}") remaining_fds = list(decomposed_F) # Step 2 & 3: Remove redundant dependencies and attributes from LHS. for i in range(len(remaining_fds)): current_fd = remaining_fds[i] # Temporarily remove this dependency to check redundancy. temp_set = {fd for j, fd in enumerate(remaining_fds) if j != i} # Check closure without it. if not is_redundant(current_fd, temp_set): # Hypothetical function checking redundancy via closures. simplified_lhs = simplify_left_side(current_fd, temp_set) # Another hypothetical helper func. minimal_cover.append(simplified_lhs) return minimal_cover ``` 以上伪代码展示了如何实现自动化寻找最小覆盖的功能。 --- ### 应用场景分析 函数依赖广泛应用于规范化过程中定义第三范式(3NF)以及BCNF的标准判定依据之上。具体来说,当设计实体间关联模型时,利用它们可以帮助识别潜在的数据异常情况——包括更新、插入及删除操作可能引发的一致性破坏风险等问题。 此外,在实际开发阶段,理解并掌握这一知识点有助于开发者更好地评估索引策略的有效性和查询性能调优方向的选择等方面工作。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值