问题 : D.求XF+闭包

题目描述

如何设计一个好的数据库不仅仅是一个理论研究问题,也是一个实际应用问题。在关系数据库中不满足规范化理论的数据库设计会存在冗余、插入异常、删除异常等现象。

     设R(U)是一个关系模式,U={A1,A2, ……, An}。其中Ai是关系的属性,X,Y是U的子集。函数依赖 XàY定义了数据库中属性集X与Y的依赖关系。根据Armstrong公理,函数依赖满足:

(1)      自反律:若Ai∈X,  则 XàAi.   特别地,Ai àAi.

(2)       增广律:若XàY,  则 ZXàZY.      (ZX 是指集合Z与X的并集 )

(3)       传递律:若XàY,  YàZ,  则 XàZ.

(4)       分解律:若XàY,  则 XàAi        ( 若属性Ai∈Y  )

(5)       合并律:若XàY,  XàZ,  则 XàYZ.

 已知 F 是关系模式R(U)上的函数依赖集,利用Armstrong公理系统可以推导出更多的函数依赖。设X是属性集U={A1,A2, ……, An} 的子集, 定义X关于F的闭包XF+

XF+={Ai | 若Xà Ai可以通过Armstrong公理导出}

对于给定的U , F,X, 请求出XF+

输入

第一行: T        表示以下有T组测试数据             ( 1≤T ≤5 )

对每组数据,

      第1行: n m  k       n 表示U中属性个数( 1≤n≤26 ), 用大写字母表示

                              m表示X中属性个数( 1≤m≤26 )

                              k个函数依赖  (1≤ k ≤20 )

      第2行:  字符串U      n个大写字母

第3行:  字符串X      m个大写字母

接下来有K行,每行有两个字符串 S T,用一个空格隔开。 表示 SàT

输出

对每组测试数据,输出占一行输出XF+,要求按字母序输出。

样例输入

16 2 4
ABGDCI
AD
A  B
BD  I
AG  C
C  D

样例输出

ABDI

解题思路:

这道题最重要的就是看懂题意,因为题目设计数据库的内容,所以刚开始基本上没看懂,后来也是请教了学长才解决的。这道题的大概意思就是按照以上的几种关系以及已经给出的关系式,推算出XF+,只要看懂了那几个关系式,其他的就简单多了,因为数据也不大,直接用最喜欢的暴力解决就行了。

程序代码:

#include<stdio.h>
#include<string.h>
int main()
{
     int s[30];
     char N[30],M[30],a[5],a1[5],x[30];
     int n,m,k,i,t,j,len,l;
     scanf ( "%d" ,&t);
     while (t--)
     {
         scanf ( "%d%d%d" ,&n,&m,&k);
         getchar ();//读入换行
         for (i=0;i<n;i++)//注意这一点,由于是多实例,所以每次都需要重新赋值
         s[i]=9999;
         gets (N);
         gets (M);
         for (i=0;i<m;i++)
         {
             for (j=0;j<n;j++)
             {
                 if (M[i]==N[j])
                 s[j]=0;
             }
         }
         while (k--)
         {
             scanf ( "%s%s" ,a,a1);
             len= strlen (a);
             if (len==2)
             {
                 for (i=0;i<n;i++)
                 {
                     if (N[i]==a[0])
                     {
                         if (s[i]!=0)
                         continue ;
                         else
                         {
                             for (j=0;j<n;j++)
                             {
                                 if (N[j]==a[1])
                                 {
                                     if (s[j]!=0)
                                     continue ;
                                     else
                                     for (l=0;l<n;l++)
                                     {
                                         if (N[l]==a1[0])
                                         s[l]=0;
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             if (len==1)
             {
                 for (i=0;i<n;i++)
                 {
                     if (N[i]==a[0]&&s[i]==0)
                     {
                         for (j=0;j<n;j++)
                         {
                             if (N[j]==a1[0])
                             {
                                 s[j]=0;
                             }
                         }
                     }
                     else
                     break ;
                 }
             }
         }
         for (i=0;i<n;i++)
         if (s[i]==0)
         printf ( "%c" ,N[i]);
         printf ( "\n" );
     }
     return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值