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

    项目 内容
    课程 2020春季计算机学院软件工程(罗杰 任健)
    这个作业的要求 个人项目作业
    教学班级 006
    项目地址 https://github.com/17373380/Personal

    PSP项目表格

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

    解题思路

    拿到题目后分析,有两种数据类型,直线和点。
    直线常见的表示形式有:

    • 一般式:Ax+By+C=0(A、B不同时为0)【适用于所有直线】
    • 点斜式:y-y0=k(x-x0) 【适用于不垂直于x轴的直线】
    • 截距式:x/a+y/b=1【适用于不过原点或不垂直于x轴、y轴的直线】
    • 斜截式:y=kx+b【适用于不垂直于x轴的直线】
    • 两点式:(y-y1)/(y2-y1)=(x-x1)/(x2-x1) (x1≠x2,y1≠y2)【适用于不垂直于x轴、y轴的直线】

    其中直线我选用ax+by+c=0的标准方程来表示,此方程可以表示平行于x轴或者平行于y轴的直线,不用特殊考虑。点再一开始我准备使用(x,y)坐标的方法来表示,但再实际操作之后发现:交点坐标绝大部分是小数,而其精度的确定成了难题,有可能依照不慎,满盘皆输。所以在细致考虑后决定使用分数来表示坐标。
    输入的数据时按行排列的,所以我就按行读取,再用空格进行分割,得到原始数据,解方程求得直线ax+by+c=0。每加入一条新直线就与之前的所有直线求解交点。

    设计实现过程

    主要函数

    函数名 作用
    int str2int(string now) 将string转化为int型。
    void Container::getNewCross(Line *nline) 求解新直线与已有直线的交点。
    Cross::Cross(Line *line1, Line *line2) 求两直线的交点。
    Line::Line(int x1, int y1, int x2, int y2) 根据两点求解直线。

    我计划构建三个类:Line,Cross,Container,分别是直线,交点和存放二者的容器。

    class Line {
    public:
    int a;
    int b;
    int c;
    Line(int x1, int y1, int x2, int y2);
    ~Line();
    void printLine();
    string line2str();
    };
    class Cross {
    public:
    int numX;
    int denX;
    int numY;
    int denY;
    Cross(Line *line1, Line *line2);
    ~Cross();
    bool operator ==(const Cross&) const;
    bool operator >(const Cross&) const;
    bool operator <(const Cross&) const;
    void printCross();
    
    };
    class Container {
    public:
    vector<Line*> *lineSet = new vector<Line*>(); //= new set<Line>();
    set<Cross> *crossSet = new set<Cross>();
    Container();
    ~Container();
    void addLine(Line *line);
    void getNewCross(Line *nLIne);
    int getCrossNum();
    void printLineSet();
    void printCrossSet();
    };
    

    存放直线与交点的数据结构分别用vector和set

    vector<Line*> *lineSet = new vector<Line*>();
    set<Cross> *crossSet = new set<Cross>();
    

    在读入直线的数量N后,进行N次循环,每次循环将新获得的直线与已有直线求解交点,并将新交点和新直线加入到容器中。

    for (i = 0; i < lines; i++) {
    	in >> type;
    	if (type == "L") {
    		in >> x1 >> y1 >> x2 >> y2;
    		Line *tempLine = new Line(x1, y1, x2, y2);
    		container.getNewCross(tempLine);
    	}
    }
    

    求解直线,只需用简单的数学知识即可。

    Line::Line(int x1, int y1, int x2, int y2) {
    if (x1 == x2) {
    	this->a = 1;
    	this->b = 0;
    	this->c = -x1;
    }
    else if (y1 == y2) {
    	this->a = 0;
    	this->b = 1;
    	this->c = -y1;
    }
    else {
    	this->a = y2 - y1;
    	this->b = x1 - x2;
    	this->c = y1 * x2 - y2 * x1;
    }
    }
    

    循环直线容器求解交点。

    Cross::Cross(Line *line1, Line *line2) {
    this->numX = line1->c * line2->b - line2->c * line1->b;
    this->denX = line1->b * line2->a - line2->b * line1->a;
    this->numY = line1->a * line2->c - line2->a * line1->c;
    this->denY = this->denX;
    if (this->numX < 0 && this->denX < 0) {
    	this->numX = -this->numX;
    	this->denX = -this->denX;
    }
    if (this->numY < 0 && this->denY < 0) {
    	this->numY = -this->numY;
    	this->denY = -this->denY;
    }
    }
    

    最后获取交点个数
    container.getCrossNum();

    单元测试的构造

    单元测试主要偏重于对边界数据以及特殊情况的构造(直线平行或相交于一点)。

    TEST_METHOD(TestMethod8)
    	{
    		Line* line1 = new Line(0, 0, 99998, 2);
    		Line* line2 = new Line(0, 2, 49999, 3);
    		Assert::IsTrue(parallel(*line1, *line2));
    	}
    TEST_METHOD(TestMethod11) {
    		Line* line1 = new Line(0, 0, 0, 1);
    		Line* line2 = new Line(0, 0, 1, 0);
    		Line* line3 = new Line(0, 0, 1, 1);
    		Line* line4 = new Line(0, 1, 1, 1);
    		Container container;
    		container.getNewCross(line1);
    		container.getNewCross(line2);
    		container.getNewCross(line3);
    		container.getNewCross(line4);
    		Assert::AreEqual(3, container.getCrossNum());
    	}
    

    性能分析

    • cpu使用
      对1000条直线计算

    • 函数分配

      大部分操作都是set树的操作。

    • 性能改进
      对set的operator判断进行了改进,
      原来将直线全部读入之后再计算交点,改进后读入一条新直线,就计算好交点。

  • 相关阅读:
    RedHat Linux下利用sersync进行实时同步数据
    curl网站开发指南
    常用命令
    Linux 查看CPU信息、机器型号等硬件信息
    -bash: crontab: command not found(转)
    端口映射工具--socat
    左右半透明的无缝滚动
    js学习笔记33----DOM操作
    Framework 7 之 给Picker Modal 添加半透明背景
    网页嵌入自定义字体方法
  • 原文地址:https://www.cnblogs.com/ybwnb/p/12450762.html
Copyright © 2011-2022 走看看