求函数依赖集闭包

本文讲解具体代码实现,相关概念可查阅资料(其实我只是想把代码保存到博客上嘿嘿
这算是我第一次能够用构建一个个类来解决一个较大的问题(不再是像考试一样在一个类里写n个函数了ORZ),在老师的指导下完成的代码,让我切身体会到了面向对象的好处。

1. 首先构建一个类存储函数依赖

当然了,要规范一下函数依赖的输入格式以及间隔符

package functionalDependence;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;public class FunctionalDependence {/*存储一个函数依赖A,B->C*/private Set<String> left;private Set<String> right;FunctionalDependence(Set<String> left, Set<String> right) {this.left = new HashSet<>(left);this.right = new HashSet<>(right);}Set<String> getLeft() {return new HashSet<>(left);    //返回拷贝值,避免传出索引值被更改}Set<String> getRight() {return new HashSet<>(right);}@Overridepublic String toString() {return left + "->" + right;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;FunctionalDependence that = (FunctionalDependence) o;return left.equals(that.left) &&right.equals(that.right);}@Overridepublic int hashCode() {return Objects.hash(left, right);}static void addToSet(String str, Set<String> set){/*将一个表示集合的字符串"A,B"中的元素加入到集合*/String[] temp = str.split(",");for(String attribute : temp){set.add(attribute);}}/*将一个表示函数依赖的字符串"A,B->C"存入类中*/static FunctionalDependence of(String fmtstr){String[] temp = fmtstr.split("->");Set<String> left = new HashSet<>();Set<String> right = new HashSet<>();addToSet(temp[0],left);addToSet(temp[1], right);return new FunctionalDependence(left,right);}}

函数依赖是集合与集合的关系,类中提供了必要的方法方便使用。

2. 需要一个求集合的所有子集的方法,把它写进自己的工具包里

实现求集合的所有子集的方法很多,这里是摘抄的一个自己已经完全理解了的方法,在代码后写上了注释。(此处划重点,这个求子集的方法也是一个好点子,值得记小本本~

package utility;import java.util.ArrayList;import java.util.HashSet;import java.util.Set;public class mySet extends HashSet {public static Set<Set<String>> subSet(Set<String> set){/*求集合的子集,集合元素为string结果以一个包含所有子集的集合返回*/ArrayList<String> list = new ArrayList<>(set);      //用ArrayList存储set中的元素Set<Set<String>> result = new HashSet<>();int n = list.size();for(int i=0; i<(1<<n); i++){//循环2^n次/*对一个集合,任取任意项或不取,所能得到的所有结果即为所有子集根据这个原理可以利用二进制码标志集合元素的选取状态来获取子集。如集合{a,b,c,d}的子集可用0000,0001,0010....来表示*/String setStr = Integer.toBinaryString(i);//将int值转换成二进制值的字符串int unChoose = n-setStr.length();   //setStr的长度m表示:这个setStr表示的是set中后m个元素的选取状态,如10表示的是"c"和"d"的状态Set<String> subSet = new HashSet<>();for(int j=0; j<setStr.length(); j++){if(setStr.charAt(j)=='1'){      //等于1表示被选,该元素加入当前子集subSet.add(list.get(unChoose+j));}}result.add(subSet);}return result;}
}

3. 构建函数依赖集的类,并将求属性闭包、函数依赖集闭包、判断是否为候选码/超码等方法写进

具体步骤都在注释里啦(当然我不相信我的注释写的能让别人能看懂代码功能ORZ,建议想学习的同学把代码拷到编译器里一点点的看具体的实现,收获应该也不少

package functionalDependence;import java.util.HashSet;
import java.util.Objects;
import java.util.Scanner;
import java.util.Set;import static utility.mySet.subSet;public class FunctionalDependenceSet<isSuperKey> extends HashSet{Set<FunctionalDependence> fds;public FunctionalDependenceSet() {this.fds = new HashSet<>();}public void add(FunctionalDependence fd){ fds.add(fd); }public void remove(FunctionalDependence fd){fds.remove(fd);}@Overridepublic String toString() {/*以分号间隔各个函数依赖*/String result = "";for(FunctionalDependence fd : fds){result += fd.toString() + ";";}return result;}public static FunctionalDependenceSet of(String fmtstr){//通过输入"A->B;A,B->C;C->D"这样的字符串创建函数依赖集FunctionalDependenceSet fds = new FunctionalDependenceSet();String[] temp = fmtstr.split(";");for(String i : temp){FunctionalDependence fd = FunctionalDependence.of(i);fds.add(fd);}return fds;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (!(o instanceof FunctionalDependenceSet)) return false;FunctionalDependenceSet that = (FunctionalDependenceSet) o;return Objects.equals(fds, that.fds);}@Overridepublic int hashCode() {return Objects.hash(fds);}public Set<String> attributeClosure(Set<String> attribute){//求某一属性的闭包Set<String> result = new HashSet<>(attribute);boolean changed = true;while (changed){//当结果集发生改变changed = false;for (FunctionalDependence fd : fds){//对结果集中每一个函数依赖进行检查if (result.containsAll(fd.getLeft()) && !result.containsAll(fd.getRight())){//如果函数依赖左边集合为结果集的子集且右边集合不是子集,则将右边集合加入结果集。并更改changed状态result.addAll(fd.getRight());changed = true;}}}return result;}public  FunctionalDependenceSet closure(){FunctionalDependenceSet result = new FunctionalDependenceSet();//1.得到函数依赖集中的所有属性Set<String> allAttributes = getAllAttributes();//2.得到所有属性的子集Set<Set<String>> attSubSet = subSet(allAttributes);//3.将每一个子集作为left,求他的属性闭包for(Set<String> left : attSubSet){Set<String> attClosure = attributeClosure(left);//4.然后再将该属性的闭包求子集,将子集作为right,将(left->right)加入函数依赖集Set<Set<String>> attClosureSubSet = subSet(attClosure);for(Set<String> right : attClosureSubSet){result.add(new FunctionalDependence(left, right));}}return result;}public Set<String> getAllAttributes() {Set<String> allAttributes = new HashSet<>();for(FunctionalDependence fd : fds){allAttributes.addAll(fd.getRight());allAttributes.addAll(fd.getLeft());}return allAttributes;}public boolean isSuperKey(Set<String> attribute){if(attributeClosure(attribute).equals(getAllAttributes())){return  true;}return false;}public boolean isCandidateKey(Set<String> attribute){if(isSuperKey(attribute)){Set<Set<String>> subSet = subSet(attribute);for(Set<String> i : subSet){if(isSuperKey(i) && !i.equals(attribute)) {return false;}}return true;}return false;}public static void control(){System.out.println("请按“A->B;B->C;A,B->D”的格式输入函数依赖:");Scanner scanner = new Scanner(System.in);String fmtstr = scanner.nextLine();FunctionalDependenceSet fds = FunctionalDependenceSet.of(fmtstr);System.out.println("请输入需要求闭包属性集,以end结束属性集的输入:");while(true){String line = scanner.nextLine();Set<String> allAttribute = fds.getAllAttributes();if(line.equals("end")) break;if(!allAttribute.contains(line)) System.out.println("输入的属性集不存在");else {Set<String> attribute = new HashSet<>();attribute.add(line);Set<String> attClosure = fds.attributeClosure(attribute);System.out.println("属性集" + line + "的闭包为" + attClosure);}}System.out.println("函数依赖的闭包为:" + fds.closure());}}

把之前在main函数里写的用来测试的代码写进了control方法。

4.写在后面

每个方法都是经过test的,只要没粘贴错应该可以直接运行的。代码单纯的是为了实现函数依赖集闭包的求取,因此健全性等不是很好(请按要求输入),仅作为学习参考啦~
体验到面向对象的好处和特点之后,刚接触炉石传说的我突然有、、想尝试用java代码模拟一下炉石传说,帮我过砰砰计划的解密关哈哈哈哈哈(dbq我太菜了后面的关越来越难过了。不过…怎么样设计类及类之间的关系才能达到一场游戏的效果可真是个难题,虽然刚考过软件系统分析与体系架构设计的课,但想真正的自己写一个有点模样的project的确不容易啊(我知道csdn下载里有源码but我目前不想冲VIP,嗯,我要自己试着写写。
暑假干巴爹

Java实现构建函数依赖与函数依赖集的类、求函数依赖集的闭包、属性集闭包、判断属性集是否为候选码/超码、求集合的全部子集相关推荐

  1. 数据库期末考试预习之候选码,最小函数依赖集,3NF分解算法,判断第几范式

    一.候选码 参考链接:1 1.定义: 候选码(超级码)就是可以被选为主码的属性或属性组.当一个关系有N个属性或属性组可以唯一标识时,则说明该关系有N个候选码,可以选定其中一个作为主码. 候选码定义: ...

  2. 基本函数依赖和候选键_[总结]关系数据库设计基础(函数依赖、无损连接性、保持函数依赖、范式、……)...

    联系(Relationship)1:1联系:如果实体集E1中的每个实体最多只能和实体集E2中一个实体有联系,反之亦然,那么实体集E1对E2的联系成为一对一联系,记为1:1: 1:N联系:一对多,记为1 ...

  3. 函数依赖 候选码 主码 第三范式 BCNF 多值依赖

    关系数据库理论 课本第六章 关系数据库理论 一.函数依赖: 1.完全函数依赖 通过AB能得出C,但是AB单独得不出C,那么说C完全依赖于AB. 2.部分函数依赖 通过AB能得出C,通过A也能得出C,通 ...

  4. 基于Java语言构建区块链(四)—— 交易(UTXO)

    基于Java语言构建区块链(四)-- 交易(UTXO) 2018年03月11日 00:48:01 wangwei_hz 阅读数:909 标签: 区块链比特币 更多 个人分类: 区块链 文章的主要思想和 ...

  5. 基于Java语言构建区块链(六)—— 交易(Merkle Tree)

    基于Java语言构建区块链(六)-- 交易(Merkle Tree) 2018年04月16日 10:21:35 wangwei_hz 阅读数:480更多 个人分类: 区块链比特币bitcoin 最终内 ...

  6. java gradle构建_在Gradle中为JPMS构建Java 6-8库

    java gradle构建 通过提供Java 9 module-info.class了解如何使用Gradle构建支持JPMS( Java平台模块系统 )的Java 6-8库. 介绍 如果您需要JPMS ...

  7. 在Java中构建响应式微服务系统——第三章 构建响应式微服务

    第三章 构建响应式微服务 在本章中,我们将使用Vert.x构建我们的第一个微服务.由于大多数微服务系统使用HTTP进行交互,因此我们将以HTTP微服务作为开始.但是由于系统包含多个相互通讯的微服务,因 ...

  8. 数据库函数依赖与候选码求解

    函数依赖 1.理解函数依赖: (1)完全函数依赖(F):多个属性[即复合属性]决定一个属性.例:AB两个属性决定属性C. (2)部分函数依赖(P):单个属性就可决定一个属性.例:A属性决定B属性 (3 ...

  9. 基于Java语言构建区块链(一)—— 基本原型

    最终内容请以原文为准:https://wangwei.one/posts/df1... 引言 区块链技术是一项比人工智能更具革命性的技术,人工智能只是提高了人类的生产力,而区块链则将改变人类社会的生产 ...

最新文章

  1. 调用枚举接口重写方法提示找不到符号_看看人家那后端API接口写得,那叫一个巴适~...
  2. ARP防治攻略————服务器防护
  3. view 背景透明
  4. 计算机二级考试Access教程
  5. Java什么是重用_深度解析:java必须掌握的知识点——类的重用
  6. 操作系统之进程管理:2、进程的状态以及状态转化
  7. 20145222何志威《网络对抗》- Web安全基础实践
  8. wireshark抓包红色_wireshark抓包常见提示含义解析
  9. 高斯定理的证明(三重积分的C/C++实现)(C++)(大学物理)
  10. vue3自定义指令(directive)
  11. 一个善意的谎言拯救一个团队 (又叫沙漠中的指南针)
  12. 巧用千寻位置GNSS软件|逐点放样应用技巧
  13. 太火爆了!这一款小游戏火到把服务器搞瘫痪,合成大西瓜
  14. 钢管车架管材的分级介绍 (zz)
  15. 什么叫32位计算机,32位是什么意思
  16. 制作ESXI6.7启动盘
  17. oracle查看历史oracle database数据库版本并下载
  18. 清华大学计算机专业的cpu,我们研制成功进入世界500强的超级计算机
  19. 3 为什么考研?该做那些准备 --绝密,程序员大厂面试求职大揭秘!
  20. 一字一句体验语言的魅力-2:80386-datasheet翻译学习-第一章完

热门文章

  1. oracle创建表空间笔记 小白专属 小白必看!(内有福利)
  2. 计算机系的对联,首个计算机对联系统问世
  3. Oracle ASM的AU(Allocation units)分配
  4. 关于旅行商,哈密顿回路和NP问题的科普
  5. 苹果手机拦截所有陌生号码,如何解除--请关闭勿扰模式
  6. xm-select下拉框,下拉树
  7. GitChat · 人工智能 | 如何零基础用 Keras 快速搭建实用深度学习模型
  8. 转载中国地理信息产业现状、问题与出路分析
  9. 青年不愿老去,“养生+奶茶”却撑不起这份骄傲倔强
  10. Linux环境怎样制作u盘系统启动盘