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;
    }
}

五.架构设计

其实本次单元的作业基本不需要自己设计什么架构,大部分的函数只要照搬JML就好了,我在设计过程中主要考虑的是如何降低函数复杂度以及该采取何种容器。只要能够解决这两个问题,就不需要考虑其他的了。像图模型的构建与维护,只要根据JML完成,就能达到目的。

 

以上是关于BUAA OO 第三单元总结的主要内容,如果未能解决你的问题,请参考以下文章

BUAA OO 第三单元总结

2020-BUAA OO-面向对象设计与构造-第三单元总结

BUAA_OO第三单元作业总结

BUAA OO 第三单元总结

BUAA_OO 第三单元总结

BUAA_OO 第四单元总结——UML