array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 BUAA 软件工程个人作业 - 爱码网
项目 内容
这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健)
这个作业的要求在哪里 个人项目作业
我在这个课程的目标是 学习软件工程的开发知识,培养工程化开发能力
这个作业在哪个具体方面帮助我实现目标 通过实操掌握PSP开发基础

 

PSP2.1 Personal 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时间分配,可以看出主要占用时间的函数

BUAA 软件工程个人作业

 

BUAA 软件工程个人作业

 

BUAA 软件工程个人作业

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

四. 代码说明

代码质量分析图

BUAA 软件工程个人作业

单元测试

BUAA 软件工程个人作业

关键函数实现

  • 圆与直线交点求解BUAA 软件工程个人作业

  • 圆与圆交点求解BUAA 软件工程个人作业

  • 直线与直线交点求解BUAA 软件工程个人作业

     

     

相关文章: