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判断进行了改进,
      原来将直线全部读入之后再计算交点,改进后读入一条新直线,就计算好交点。

  • 相关阅读:
    Working with macro signatures
    Reset and Clear Recent Items and Frequent Places in Windows 10
    git分支演示
    The current .NET SDK does not support targeting .NET Core 2.1. Either target .NET Core 2.0 or lower, or use a version of the .NET SDK that supports .NET Core 2.1.
    Build website project by roslyn through devenv.com
    Configure environment variables for different tools in jenkins
    NUnit Console Command Line
    Code Coverage and Unit Test in SonarQube
    头脑王者 物理化学生物
    头脑王者 常识,饮食
  • 原文地址:https://www.cnblogs.com/ybwnb/p/12450762.html
Copyright © 2011-2022 走看看