• 个人项目作业


    个人项目作业

    项目 内容
    作业所属课程 2020春季计算机学院软件工程(罗杰,任健)
    作业要求 个人项目作业
    教学班级 005
    项目地址 个人项目地址

    PSP表格

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

    解题思路

    对于给定的N条直线,询问平面中有多少点在至少2条给定的直线上,即求出N条直线有多少不重复的交点。

    首先我分析到输入部分,每条直线对应线上不同的两点,我首先根据这两点计算得到直线的标准方程式,记得到三个重要参数:a, b, c:
    $$
    ax + by + c = 0, a = y2 - y1, b = x1 - x2, c = y1x2 - x1y2;
    $$
    同时我们保证a始终大于0。

    得到每个直线的标准方程式后,我们就可以进行两两比较得到交点数了,若两条直线的斜率不等,则说明两条直线有交点,同时记录交点的坐标信息:
    $$
    x = (b1c2 - c1b2)/(a1b2 - a2b1), y = (a2c1 - a1c2)/(a1b2 - a2b1);
    $$
    在比对所有直线的相交情况后,我们就可以去掉计数了重复的点了,最后得到就是所有直线不重复的交点,即平面中至少在2条给点直线上的点数。

    设计实现

    程序中有四个函数,设计了两个结构体:

    直线标准式信息(LINE):

    记录了每条直线的a, b, c相应的值,采用double数据类型。

    交点坐标信息(Point2d):

    记录每个交点的坐标轴信息,包括x, y,采用double数据类型。

    主函数(main):

    主要用于命令行的输入输出,首先对命令行进行处理得到所要的数据,将每个直线的两点坐标信息读取传递给调用函数,返回得到直线标准方程式信息,然后调用计算交点数函数得到无重复的交点个数,返回到输出文件中。

    直线标准方程式函数(makeline):

    根据所给的直线两点坐标,计算得到直线标准式a, b, c值,其中保证a值大于0,,返回一个LINE数据结构体。

    计算交点函数(calculateCrossPointsNum):

    遍历每条直线,查看两两直线是否相交,统计并记录交点坐标信息,然后遍历交点信息,取出重复的交点。

    判断直线是否相交函数(lineintersect):

    通过比较所给两条直线的斜率,分析两条直线是否平行,若直线相交计算并记录交点的坐标信息。

    函数之间的关系:

    主函数main通过调用makeline来根据点的坐标信息得到直线的标准式信息,然后通过calculateCrossPointsNum计算得到交点个数,calculateCrossPointsNum函数调用lineintersect来判断两两直线是否相交:

    单元测试主要根据样例分析多种不同情况,考虑一条直线,多条直线相交一点,多条平行线等问题,均可实现。

    性能分析表

    性能分析图(由 VS 2019 的性能分析工具自动生成) :

    程序中消耗最大的是比较斜率过程。

    代码说明

    通过命令行输入直线数据:

    int main(int argc, char* argv[])
    {
    	ifstream in;
    	ofstream out;
    	for (int i = 0; i < argc; i++) {
    		if ((string)argv[i] == "-i") {
    			in.open(argv[i + 1]);
    		}
    		else if ((string)argv[i] == "-o") {
    			out.open(argv[i + 1]);
    		}
    	}
    
        int N; // 直线个数
    	in >> N;
    

    根据已知两点坐标,求过这两点的直线解析方程:a*x + b * y + c = 0:

    LINE makeline(double x1,double y1,double x2,double y2)
    {
        LINE tl;
        int sign = 1;
        tl.a = y2 - y1;
        if (tl.a < 0) {
            sign = -1;
            tl.a = sign * tl.a;
        }
        tl.b = sign * (x1 - x2);
        tl.c = sign * (y1 * x2 - x1 * y2);
        return tl;
    }
    

    如果两条直线 l1(a1x+b1y+c1 = 0), l2(a2x+b2y+c2 = 0)相交,返回true,且返回交点p:

    bool lineintersect(LINE l1, LINE l2, Point2d &p)
    {
        double d = l1.a * l2.b - l2.a * l1.b;
        if (abs(d) < EP)
        {
            return false;
        }
        p.x = (l2.c * l1.b - l1.c * l2.b) / d;
        p.y = (l2.a * l1.c - l1.a * l2.c) / d;
        return true;
    }
    
    

    去掉重复点:

    for (int i = 0; i < pnts.size() - 1; i++)
        {
            for (int j = i + 1; j < pnts.size(); j++)
            {
                if (pnts[i].x == pnts[j].x && pnts[i].y == pnts[j].y)
                {
                    pnts.erase(pnts.begin() + j);
                    j--;
                }
            }
        }
    

    Code Quality Analysis分析

  • 相关阅读:
    Part 3:视图和模板--Django从入门到精通系列教程
    Part 2:模型与后台管理admin站点--Django从入门到精通系列教程
    Part 1:请求与响应--Django从入门到精通系列教程
    java的static关键字
    接口
    final关键字
    抽象类
    动态绑定多态
    对象转型2
    对象转型1
  • 原文地址:https://www.cnblogs.com/zl747852583/p/12454770.html
Copyright © 2020-2023  润新知