首页 > 其他分享 >结对项目

结对项目

时间:2024-09-22 21:12:53浏览次数:1  
标签:结对 op1 项目 number son vector mum string

目录

结对项目

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13230
这个作业的目标 实现一个自动生成小学四则运算题目的命令行程序
项目github地址 github
项目成员 黄博

1. PSP2.1表格

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

2.性能分析

以上为自己创建式子的函数火焰图

可以发现大体时间用于创建式子,这里的创建平均时间复杂度为O(nlogn),每一次都使用随机决定数字或字符,在一个式子创建完成后丢入检测是否有子运算<0,如果有就重新生成

void create() { // 生成问题
    vector<string> pro;
    for (int i = 0; i < num; i++) {
        string now = getstring();
        now = pplus(now);
        number tt = check(now);
        while (tt.son < 0 || tt.mum < 0) {
            now = getstring();
            now = pplus(now);
            tt = check(now);
        }
        pro.push_back(now);
    }
    std::ofstream file(outfile1);
    if (!file.is_open()) {
        cout << "Can't open file:" << outfile1 << endl;
        exit(0);
    }
    for (int i = 0; i < pro.size(); i++) file << i + 1 << "." << pro[i] << endl;
}
string getstring() { // 生成每一个字符串
    string now = "";
    int cnt = prolen(sj) + 1;
    for (int i = 0; i < cnt; i++) {
        int num1 = promaxm(sj);
        string op1 = op[proop(sj)];
        now += to_string(num1);
        if (i != cnt - 1) now += op1;
    }
    return now;
}
string pplus(string s) {
    string now = "";
    int cnt1 = 0;
    for (int i = 0, flag = 1; i < s.size(); i++) {
        if (isdigit(s[i])) {
            if (flag) {
                flag = 0;
                if (plusop(sj) % 10 == 0) {
                    now += '(';
                    cnt1++;
                }
            }
        } else {
            if (!flag && cnt1 && plusop(sj) % 12 == 0) {
                now += ')';
                cnt1--;
            }
            flag = 1;
        }
        now += s[i];
    }
    for (int i = 0; i < cnt1; i++) {
        now += ')';
    }
    // cout << now << endl;
    return now;
}
number check(string s) {
    // 获取操作符优先级
    auto get_op = [&](char op1) {
        if (op1 == '+' || op1 == '-') return 1;
        if (op1 == '*' || op1 == '/') return 2;
        return 0;
    };
    // 计算两个数的运算结果,同时判断是否为负数
    auto cul = [&](number a, number b, char op1) {
        number result(0, 1);
        switch (op1) {
        case '+':
            result = a + b;
            break;
        case '-':
            result = a - b;
            break;
        case '*':
            result = a * b;
            break;
        case '/':
            // 检查是否除以 0
            if (b.son == 0) {
                // cout << "Error: Division by zero!" << endl;
                return number(0, 1); // 返回默认分数 0/1
            }
            result = a / b;
            break;
        default:
            return number(0, 1); // 不应该到达这里,返回默认分数 0/1
        }
        if (result.son < 0) {
            result.son = -1, result.mum = -1;
            return result; // 如果结果为负,返回 (-inf, -inf)
        }
        return result;
    };

    stack<number> values; // 用于存储分数的栈
    stack<char> ops;      // 用于存储操作符的栈

    for (int i = 0; i < s.size(); ++i) {
        if (isdigit(s[i])) {
            int num = 0;
            while (i < s.size() && isdigit(s[i])) {
                num = num * 10 + (s[i] - '0');
                i++;
            }
            values.push(number(num, 1)); // 将数字作为分数推入栈,分母设置为 1
            i--;
        }
        // 处理左括号
        else if (s[i] == '(') {
            ops.push('(');
        } else if (s[i] == ')') {
            while (!ops.empty() && ops.top() != '(') {
                number val2 = values.top();
                values.pop();
                number val1 = values.top();
                values.pop();
                char op1 = ops.top();
                ops.pop();
                number result = cul(val1, val2, op1);

                if (result.son < 0 || result.mum < 0) {
                    // cout << "a" << endl;
                    return result;
                }
                values.push(result); // 计算两个数并推入栈
            }
            ops.pop(); // 弹出左括号
        }
        // 处理操作符
        else if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') {
            while (!ops.empty() && get_op(ops.top()) >= get_op(s[i])) {
                number val2 = values.top();
                values.pop();
                number val1 = values.top();
                values.pop();
                char op1 = ops.top();
                ops.pop();
                number result = cul(val1, val2, op1);

                if (result.son < 0 || result.mum < 0) {
                    // cout << "b" << endl;
                    return result;
                }
                values.push(result);
            }
            ops.push(s[i]); // 将当前操作符压入栈
        }
    }

    // 处理剩余操作符
    while (!ops.empty()) {
        number val2 = values.top();
        values.pop();
        number val1 = values.top();
        values.pop();
        char op1 = ops.top();
        ops.pop();
        number result = cul(val1, val2, op1);
        if (result.son < 0 || result.mum < 0) {
            // cout << "c" << endl;
            return result;
        }
        values.push(result);
    }
    number final_result = values.top();
    return final_result; // 返回最终的计算结果
}

3.设计实现过程

1.结构

1.number

number结构为分数结构,蕴含一个分子和分母,在里面重载了分数的加减乘除运算,方便简略后面的运算

2.函数

1.solve()

void solve(int flag)

solve接受一个flag的值表示是自己生成题目还是读取题目进行比较

2.create()

void create()

当flag=1时,被solve(1)调用,用于生成指定数量个四则运算

3.getstring()

string getstring()

被create调用,用于生成一个完整的字符串

4.pplus(string s)

string pplus(string s)

被create调用,接受一个字符串,为其添加括号

5.check(string s)

number check(string s)

接受一个字符串,返回四则运算的值

如果返回值分子分母都为-1,则说明存在子运算小于0,被create调用和被work调用用于计算

6.read(string s)

vector<string> read(string s)

接受一个文件名字符串,读入该文件,根据序号读出所有的四则运算,并返回

7. work(vector pro)

vector<string> work(vector<string> pro)

接受一个问题组,计算出结果之后返回一个答案组

8.write1(vector ans)

void write1(vector<string> ans)

接受答案组在自己生成时往文件中写入答案

9.compare(vector ans, vector ans1)

void compare(vector<string> ans, vector<string> ans1)

在solve(2)时对两个答案组进行答案匹配

10.write2(vector right, vector wrong)

void write2(vector<int> right, vector<int> wrong)

被compare调用,接受一个错误答案组和一个正确答案组,然后输出到grade中

3.流程图

4.代码说明

核心代码

1.number类

写了个构造函数和+-*/=的重载,方便运算

struct number {
    int son, mum; // 构造函数
    number(int n = 0, int d = 1) : son(n), mum(d) {
        simplify();
    }
    void simplify() {
        int g = gcd(abs(son), abs(mum));
        son /= g, mum /= g;
        if (mum < 0) {
            son = -son;
            mum = -mum;
        }
    }
    number operator+(const number& other) const { // 分数加法
        return number(son * other.mum + other.son * mum, mum * other.mum);
    }
    number operator-(const number& other) const { // 分数减法
        return number(son * other.mum - other.son * mum, mum * other.mum);
    }
    number operator*(const number& other) const { // 分数乘法
        return number(son * other.son, mum * other.mum);
    }
    number operator/(const number& other) const { // 分数除法
        return number(son * other.mum, mum * other.son);
    }
    number& operator=(const number& other) {
        if (this != &other) { // 防止自我赋值
            son = other.son;
            mum = other.mum;
            simplify(); // 确保赋值后仍然是简化的形式
        }
        return *this;
    }
};

2.check函数

用一个数字栈和一个符号栈进行模拟,遇到左括号就推入符号栈,遇到右括号就一直弹符号栈和数字栈进行运算,过程中遇到乘除法先计算.

最后栈中只会有加减法,依次运算即可

number check(string s) {
    // 获取操作符优先级
    auto get_op = [&](char op1) {
        if (op1 == '+' || op1 == '-') return 1;
        if (op1 == '*' || op1 == '/') return 2;
        return 0;
    };
    // 计算两个数的运算结果,同时判断是否为负数
    auto cul = [&](number a, number b, char op1) {
        number result(0, 1);
        switch (op1) {
        case '+':
            result = a + b;
            break;
        case '-':
            result = a - b;
            break;
        case '*':
            result = a * b;
            break;
        case '/':
            // 检查是否除以 0
            if (b.son == 0) {
                // cout << "Error: Division by zero!" << endl;
                return number(0, 1); // 返回默认分数 0/1
            }
            result = a / b;
            break;
        default:
            return number(0, 1); // 不应该到达这里,返回默认分数 0/1
        }
        if (result.son < 0) {
            result.son = -1, result.mum = -1;
            return result; // 如果结果为负,返回 (-inf, -inf)
        }
        return result;
    };

    stack<number> values; // 用于存储分数的栈
    stack<char> ops;      // 用于存储操作符的栈

    for (int i = 0; i < s.size(); ++i) {
        if (isdigit(s[i])) {
            int num = 0;
            while (i < s.size() && isdigit(s[i])) {
                num = num * 10 + (s[i] - '0');
                i++;
            }
            values.push(number(num, 1)); // 将数字作为分数推入栈,分母设置为 1
            i--;
        }
        // 处理左括号
        else if (s[i] == '(') {
            ops.push('(');
        } else if (s[i] == ')') {
            while (!ops.empty() && ops.top() != '(') {
                number val2 = values.top();
                values.pop();
                number val1 = values.top();
                values.pop();
                char op1 = ops.top();
                ops.pop();
                number result = cul(val1, val2, op1);

                if (result.son < 0 || result.mum < 0) {
                    // cout << "a" << endl;
                    return result;
                }
                values.push(result); // 计算两个数并推入栈
            }
            ops.pop(); // 弹出左括号
        }
        // 处理操作符
        else if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') {
            while (!ops.empty() && get_op(ops.top()) >= get_op(s[i])) {
                number val2 = values.top();
                values.pop();
                number val1 = values.top();
                values.pop();
                char op1 = ops.top();
                ops.pop();
                number result = cul(val1, val2, op1);

                if (result.son < 0 || result.mum < 0) {
                    // cout << "b" << endl;
                    return result;
                }
                values.push(result);
            }
            ops.push(s[i]); // 将当前操作符压入栈
        }
    }

    // 处理剩余操作符
    while (!ops.empty()) {
        number val2 = values.top();
        values.pop();
        number val1 = values.top();
        values.pop();
        char op1 = ops.top();
        ops.pop();
        number result = cul(val1, val2, op1);
        if (result.son < 0 || result.mum < 0) {
            // cout << "c" << endl;
            return result;
        }
        values.push(result);
    }
    number final_result = values.top();
    return final_result; // 返回最终的计算结果
}

5.项目小结

看了下这次的作业虽然要求结对,但是仔细看了眼要求发现是一个模拟题,所以直接一个人做了.

主要遇到的问题在于以前没有试着不那么丑陋的写一个大模拟的代码,所以在整个依托代码分化为各个函数时怎么分化好看点用了点时间

由于一个人做完了,没什么结对感受

标签:结对,op1,项目,number,son,vector,mum,string
From: https://www.cnblogs.com/F9O1/p/18425873

相关文章

  • springboot大学生校园租房网站ssm毕业设计项目
    目录项目介绍技术栈具体实现截图开发核心技术:开发工具和技术详细视频演示核心代码部分展示系统设计操作可行性可行性论证系统测试个人心得详细视频演示源码获取方式项目介绍本javaweb+maven项目采用的数据库是Mysql,使用Springboot框架开发,十分方便,也具有跨平台的优......
  • 从代码到部署:GitHub Actions实现Java项目CI/CD的完整实践
    从代码到部署:GitHubActions实现Java项目CI/CD的完整实践在现代软件开发中,持续集成和持续部署(CI/CD)已经成为了团队高效交付代码的关键策略。通过GitHubActions,可以轻松配置CI/CD流水线,实现从代码提交到部署的自动化工作流。本文将基于英语听力网站(studytool.site)项目介......
  • golang 项目引入私有仓库包
    场景:当你多个项目,都需要使用一个或者多个方法,那么可以将公共方法,抽成一个包,进行管理(类似Log模块等)。这时候可以将你的包上传到私有的仓库,其他项目引入该包即可。下面来介绍下,如何引用私有仓库的包。1. 创建一个新的Git标签假设你已经在你的私有GitLab仓库目录中,并且你已经......
  • 结对项目:四则运算题目生成
    这个作业属于哪个课程22级计科1班这个作业要求在哪里作业要求这个作业的目标自动生成小学四则运算题目github项目链接链接姓名&学号姓名学号万凯毅3122004788周彦安3122004804PSPPSP2.1PersonalSoftwareProcessStages预估耗时(......
  • Shiro漏洞复现-springboot运行报错的解决 && 项目本地tomcat部署
    一、Springboot项目运行出现的种种问题:首先需要下载环境代码,来源Github等开源平台,下载解压后使用IDEA打开,由于Shiro通常与Springboot项目捆绑,所以通常运行需要Springboot环境,如下图所示:运行时可能会出现如下报错:unabletostartServletWebServerApplicationcontextd......
  • idea运行java项目main方法报build failure
    当你在IntelliJIDEA中运行Java项目的main方法时遇到buildfailure,这通常意味着构建过程中出现了问题。以下是一些常见的原因和解决方法:1.检查构建日志首先,查看构建日志以获取详细的错误信息。构建日志通常会显示具体的错误原因,帮助你定位问题。2.检查依赖项确保所有依赖......
  • spring boot 项目中集成使用 Elasticsearch
    目录前言一、添加依赖二、配置Elasticsearch三、定义实体和仓库四、使用Elasticsearch五、性能和安全优化六、监控和日志七、插件和扩展总结前言在SpringBoot项目中使用Elasticsearch,可以充分发挥Elasticsearch在全文搜索、日志分析、数据索引等方面的......
  • 【蓝桥杯】2024.9.22算法赛——灵魂问题\全栈项目小组(C++)
    一、灵魂问题题目灵魂问题题目分析1.要求输出一个整数2.题目在玩脑筋急转弯,关键句子标出来了——糖什么的根本不重要。所以咖啡不加糖,答案是0!!!代码#include<iostream>usingnamespacestd;intmain(){ cout<<0; return0;}二、全栈项目小组题目全栈项目小组......
  • 商城项目改进分布式缓存下的登录逻辑和页面展示-----商城项目
    packagecom.alatus.mall.auth.app;importcom.alatus.common.constant.AuthServerConstant;importcom.alatus.common.exception.BizCodeEnum;importcom.alatus.common.utils.R;importcom.alatus.common.vo.MemberRespVo;importcom.alatus.mall.auth.feign.MemberFe......
  • JAVA开源项目 甘肃非物质文化网站 计算机毕业设计
    本文项目编号T042,文末自助获取源码\color{red}{T042,文末自助获取源码}......