zoukankan      html  css  js  c++  java
  • BUAA 软件工程个人作业

    BUAA 软件工程 个人项目作业

    项目内容
    这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健)
    这个作业的要求在哪里 个人项目作业
    我在这个课程的目标是 学习软件工程的开发知识,培养工程化开发能力
    这个作业在哪个具体方面帮助我实现目标 通过实操掌握PSP开发基础

     

    PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
    Planning 计划 10 10
    · Estimate · 估计这个任务需要多少时间 10 10
    Development 开发 280 520
    · Analysis · 需求分析 (包括学习新技术) 30 40
    · Design Spec · 生成设计文档 30 40
    · Design Review · 设计复审 (和同事审核设计文档) 10 20
    · Coding Standard · 代码规范 (为目前的开发制定合适的规范) 10 20
    · Design · 具体设计 60 100
    · Coding · 具体编码 60 120
    · Code Review · 代码复审 20 60
    · Test · 测试(自我测试,修改代码,提交修改) 60 120
    Reporting 报告 70 70
    · Test Report · 测试报告 40 40
    · Size Measurement · 计算工作量 10 10
    · Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 20 20
      合计 360 600

    一. 解题思路描述

    上网搜索

    尝试在网络上找到复杂度低于o(n^2)的算法,找到一个涉及线段与线段交点的o(nlogn),关于直线搜寻无果

    解题思路

    写代码前,并未找到优秀的算法,于是选择暴力求解,即读入一条直线,立即与前n条直线进行相交求解,每一个求解得到的点都需要进行去重处理,即便理vector寻找相同点,复杂度极高。

    改进

    将点的横纵坐标组成string,形成key,选取哈希存储,即横纵坐标成为哈希列表的key值,value值为点这个结构体,这是写代码前的想法

    二. 设计实现过程

    由于是较为简单的C++代码,并没有刻意使用面向对象的思路

    • class: Function(即整个程序本体,为方便进行Test时,直接调用接口

      • set<Node, cmp> nodes:写代码时使用set而不是hashmap,是由于hashmap的开销远大于set,需要多出一个double转string的过程,可能存在精度损失,开销亦极大

      • void getLinePara: 使用ax + b = cy的方式代表直线,而不是使用最初的y = kx + b是为了减少除法的使用,最大限度保留数据的精度和准确性,读入直线时,调用此函数,获取a b c的数值,存入直线的结构体种

      • void readFile: 使用本函数进行文件读入,并将所有的Line存入vector<Line>Lines中

      • bool L2LIsCross: 使用本函数求解直线与直线的交点,即解二元一次方程组,求解前会先判断直线是否存在交点,求解得到焦点后立刻存入nodes中,并返回true,否则不存在交点,返回false

      • bool C2LIsCross: 使用本函数求解圆与直线的交点,根据圆心以及给出直线的垂线斜率,得到过圆心关于给出直线的垂线,后求出两直线的交点,根据交点到圆心的距离,判断相交相切相离,若相离,则返回false;否则,得到给出直线的正负单位向量,分别乘以与圆交线段的一半,计即可得到两个交点的坐标,返回true

      • bool C2LIsCross: 使用本函数求解两个圆的交点,首先利用圆的方程相减,得到过焦点的直线的方程,简化为求直线与圆的交点问题,直接调用函数即可

      • int Solve: 调用上述函数,完成读入到求出交点个数的过程,方便test接口使用

    • pair: Node(存放点的typedef,并未使用结构体,而是用了pair)

    • struct: Line (存放直线的结构体,包括两个点的横纵坐标,使用long存储,以及ax + b = cy中的a, b, c)

    • struct: Circle(存放圆的结构体,包括圆心node以及半径r)

    小tricks:

    • 使用set<pair>,无需double转string,减少大量工作量

    • 重写set中pair的比较函数,保证精度达到小数点后12位

    单元测试

    • 考虑极端情况,直线平行,直线垂直,直线与圆相交,直线与圆相切,直线与圆相离,圆与圆相交,圆与圆内含,圆与圆相切

    • 压力测试,2000条直线,进行测试

    三. 性能测试

    根据总CPU时间分配,可以看出主要占用时间的函数

    可以看出set.insert函数,消耗最大,也可以理解,而第一版代码中使用的hashmap,由于需要double转string,其消耗极大,甚至超过了向hashmap中插入的消耗,因此改进为使用set,红黑树存储,既可以保证不出现重复,又可以减少不必要的消耗,而向set中插入pair的方法,我并没有太多的好办法进行优化。

    四. 代码说明

    代码质量分析图

    单元测试

    关键函数实现

    • 圆与直线交点求解

    • 圆与圆交点求解

    • 直线与直线交点求解

  • 相关阅读:
    如何多个router 进行合并?
    钉钉微应用开发
    vscode 常用命令行
    window.location.search 为何在url 带# 号时获取不到 ?
    如何在嵌套的app中运用vue去写单页面H5
    两秒内不能重复点击
    linux系统下安装dubbo-admin
    二、SpringBoot实现上传文件到fastDFS文件服务器
    一、手把手教你docker搭建fastDFS文件上传下载服务器
    idea中git远程版本回退
  • 原文地址:https://www.cnblogs.com/JordenQiao/p/12456865.html
Copyright © 2011-2022 走看看