BUAA OO 第三单元总结
Posted 瘋不覺
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BUAA OO 第三单元总结相关的知识,希望对你有一定的参考价值。
BUAA OO 第三单元总结
一.设计策略
在编写函数时我基本上是先通过函数名称明白该函数大概的作用,接着再分析JML规格进行自己的优化,最后完成函数
二.基于JML规格来设计测试的方法和策略
由于本人较懒。因此并没有用课程组推荐的软件进行测试,在中测提交之前只是单纯的代入样例进行测试。
后期由于添加了许多函数导致中测出错,因此去向hxd特意求了一份自动化的评测机进行对拍。
其实在本单元中最容易出现的错误就是TLE,因此基本上每次TLE时都大概能知道自己还有哪些函数需要优化,优化过程也比较方便,逻辑错误倒是很少出现。
三.容器的选择和使用经验
在本次作业中,我采用的关键容器有两种,一种是Hashmap,另一种是PriorityQueue。
Hashmap
在本单元中除了需要区别先后的数组,其余的几乎所有数组都可以由Hashmap实现,这么做的最大的好处就是能减少复杂度,修改、查询数组内数据时都十分方便。
PriorityQueue
这个容器是在寻找最短路径的迪杰斯特拉算法中使用到的,由于其具有数据从小到大排列的性质,因此可以很方便的取出路径最短的节点来进行遍历查找,能够有效降低时间复杂度。
四.性能问题
第一次作业
我采取了并查集来判断两个节点是否连通,同时加入了路径压缩以降低复杂度。
1 public class UnionFind { 2 private int sum; 3 private int setCount; 4 private HashMap<Integer, Integer> parent = new HashMap<Integer, Integer>(); 5 6 public UnionFind() { 7 this.sum = 0; 8 this.setCount = 0; 9 } 10 11 public void addPerson(int id) { 12 parent.put(id, id); 13 sum++; 14 setCount++; 15 } 16 17 public int findset(int id) { 18 if (parent.get(id) == id) { 19 return id; 20 } else { 21 parent.replace(id, findset(parent.get(id))); 22 return parent.get(id); 23 } 24 } 25 26 public boolean unite(int id1, int id2) { 27 int x = findset(id1); 28 int y = findset(id2); 29 if (x == y) { 30 return false; 31 } 32 parent.replace(y, x); 33 setCount--; 34 return true; 35 } 36 37 public boolean connected(int id1, int id2) { 38 return findset(id1) == findset(id2); 39 } 40 41 public int getSetCount() { 42 return setCount; 43 } 44 }
第二次作业
第二次作业中的Group内的许多求和函数若完全照搬JML内的说明,那么其时间复杂度会高达o(n^2),而我也因此在互测中被hack了一刀。
我的改进方法是,将val作为属性,在增添人员或关系时对value进行增减。同时将年龄的和以及平方和也作为属性,在增添人员时增减,这样在计算年龄时也能通过公式很快得出。
第三次作业
第三次作业中最主要的性能问题就是找图的最短路径,在此,我采用了迪杰斯特拉算法。
节点
public class Pair implements Comparable<Pair> { private int id; private int dist; private HashMap<Integer, Integer> value; public Pair(int id, int dist, HashMap<Integer, Integer> value) { this.id = id; this.dist = dist; this.value = value; } public int getId() { return id; } public int getDist() { return dist; } public Set<Integer> getIdSet() { return value.keySet(); } @Override public int compareTo(Pair p) { return Integer.compare(dist, p.getDist()); } }
路径
public class Path { private PriorityQueue<Pair> queue; private HashSet<Integer> sets; private HashMap<Integer, Person> people; public Path(HashMap<Integer, Person> people) { this.queue = new PriorityQueue<>(); this.sets = new HashSet<>(); this.people = people; } public int cal(MyPerson p1, MyPerson p2) { queue.add(new Pair(p1.getId(), 0, p1.getValue())); while (!queue.isEmpty()) { Pair pair = queue.poll(); if (sets.contains(pair.getId())) { continue; } else if (pair.getId() == p2.getId()) { return pair.getDist(); } sets.add(pair.getId()); Set<Integer> idSet = pair.getIdSet(); for (int id : idSet) { MyPerson pp1 = (MyPerson) people.get(pair.getId()); MyPerson pp2 = (MyPerson) people.get(id); queue.add(new Pair(pp2.getId(), pair.getDist() + pp1.queryValue(pp2) , pp2.getValue())); } } return 0; } }
五.架构设计
以上是关于BUAA OO 第三单元总结的主要内容,如果未能解决你的问题,请参考以下文章