首页 > 编程语言 >结对编程-小学四则运算

结对编程-小学四则运算

时间:2023-09-27 20:33:41浏览次数:58  
标签:结对 编程 get int 四则运算 List 运算符 30 new

结对编程——小学四则运算

这个作业属于哪个课程

软件工程

这个作业要求在哪里

软件工程

这个作业的目标

1、尝试结对编程
2、深入熟悉开发过程
3、设计一个能自动生成小学四则运算题并批改题目的程序

 

一、合作者

姓名

学号

郑佳媚

3221005071

张萱文

3221005070

github

https://github.com/Siomun/Siomun/tree/master/FourOperation

二、PSP表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

30

30

· Estimate

· 估计这个任务需要多少时间

30

30

Development

开发

120

150

· Analysis

· 需求分析 (包括学习新技术)

30

25

· Design Spec

· 生成设计文档

30

35

· Design Review

· 设计复审 (和同事审核设计文档)

30

25

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

15

15

· Design

· 具体设计

60

50

· Coding

· 具体编码

400

480

· Code Review

· 代码复审

20

15

· Test

· 测试(自我测试,修改代码,提交修改)

60

70

Reporting

报告

80

75

· Test Report

· 测试报告

30

25

· Size Measurement

· 计算工作量

30

20

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

30

30

合计

 

895

1015

三、效能分析

 

性能分析图

 

四、设计实现过程

1、代码组织

 

五、代码说明

 

// 说明:用于过滤重复的表达式
// 思路:按顺序层层筛选,由于转换成后缀表达式,不用考虑括号
//   a. 先去除运算过程含负数的
//   b. 先比较结果
//   c. 比较表达式是否一样
//   d. 再比较包含的运算符是否相同
//   e. 比较第一次运算的两数是否只是交换位置
public static List<Equation> filter(List<Equation> list){
        for(int i=0;i < list.size();i++){
            Equation equation = list.get(i);
            //如果运算过程含负数,则跳过
            if(equation.isOf()){
                list.remove(equation);
                //remove会整体前移
                i--;
                continue;
            }
            //和整个list比较
            //标签方便下面层层嵌套能直接goto出来
            flag:
            for(int o=0;o< list.size();o++){
                Equation toCompare = list.get(o);
                //删除后有空位,要跳过
                if(toCompare == null){
                    continue;
                }
                //遇到自己就跳过
                if(equation == toCompare){
                    continue;
                }
                //先比较结果
                if(Math.abs(equation.getResult() - toCompare.getResult()) < 0.000001) {
                    //结果相同,看是否完全一样
                    if(equation.equals(toCompare)){
                        list.remove(equation);
                        //remove会整体前移
                        i--;
                        break flag;
                    }
                    //再比较运算符
                    List<Arithmetic> postfix1 = equation.getPostfix();
                    List<Arithmetic> postfix2 = toCompare.getPostfix();
                    List<Operator> operators1 = equation.getOperators();
                    List<Operator> operators2 = toCompare.getOperators();
                    //有不同运算符就保留
                    if(operators1.size() != operators2.size()){
                        break flag;
                    }
                    for(int j=0;j<operators1.size();j++){
                        if(operators1.get(j) != operators2.get(j)){
                            break flag;
                        }
                    }
 
                    //运算符相同,只比较第一次计算的两数字是否交换位置
                    //找到第一个运算符,取前两个数字
                    List<Operand> operands1 = new ArrayList<>();
                    List<Operand> operands2 = new ArrayList<>();
                    for(int j=0;j<postfix1.size();j++){
                        if(postfix1.get(j) instanceof Operator){
                            operands1.add((Operand) postfix1.get(j-1));
                            operands1.add((Operand) postfix1.get(j-2));
                            break;
                        }
                    }
                    for(int j=0;j<postfix1.size();j++){
                        if(postfix2.get(j) instanceof Operator){
                            operands2.add((Operand) postfix2.get(j-1));
                            operands2.add((Operand) postfix2.get(j-2));
                            break;
                        }
                    }
                    //比较两对数字
                    if((operands1.get(0).equals(operands2.get(0)) || operands1.get(0).equals(operands2.get(1)))
                            && (operands1.get(1).equals(operands2.get(0)) || operands1.get(1).equals(operands2.get(1)))){
                        list.remove(equation);
                        //remove会整体前移
                        i--;
                        break flag;
                    }else{
                        //两对数字不相同,保留
                        break flag;
                    }
                }else{
                    //结果不一样,保留
                    break flag;
                }
            }
 
        }
        return list.stream().toList();
    }


// generate()
// ● 说明:用于生成随机表达式
// ● 思路:通过传参确定此次生成中包含的操作数数量、运算符数量、括号数量、数的范围,然后随机new出各对象,交替拼接操作数和运算符,最后随机添加括号
public static Equation generate(int operandNo, int operatorNo, int bracketsNo
            , int lowEnd, int upEnd){
        Random r = new Random();
        int scope = upEnd - lowEnd;
        List<Arithmetic> arithmetics = new ArrayList<>();
        List<Operand> operands = new ArrayList<>();
        List<Operator> operators = new ArrayList<>();
        List<Brackets> brackets = new ArrayList<>();
 
        try {
            for (int i = 0; i < operandNo; i++) {
                // 操作数类型 自然数(0),真分数(1)
                int type = r.nextInt(10)%2;
                if(0 == type){
                    //生成随机整数
                    operands.add(new Operand(type, r.nextInt(scope) + lowEnd + ""));
                }else if (1 == type){
                    //生成真分数
                    int denominator = r.nextInt(scope) + lowEnd + 1;
                    // 分子 > 0
                    int numerator = r.nextInt(denominator - 1) + 1;
                    String str = numerator + "/" + denominator;
                    operands.add(new Operand(type, str));
                }
            }
 
            for (int i = 0; i < operatorNo; i++) {
                // 除去等号
                int index = r.nextInt(4) + 1;
                operators.add(Operator.getByIndex(index));
            }
 
            for (int i = 0; i < bracketsNo; i++) {
                brackets.add(Brackets.getByIndex(0));
                brackets.add(Brackets.getByIndex(1));
            }
 
            for (int i = 0; i < operands.size(); i++) {
                if(operands.get(i) != null){
                    arithmetics.add(operands.get(i));
                }
                if(i == operands.size()-1){
                    break;
                }
                if(operators.get(i) != null) {
                    arithmetics.add(operators.get(i));
                }
            }

        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        return new Equation(arithmetics);
    }



// 1.扫描中缀表达式的每一个字符,将数字入列;
// 2.遇到运算符,栈空时直接进栈,栈顶非空时,运算符优先级大于栈顶元素才进栈,
// 否则栈顶元素退栈入列,当前运算符再进栈;
// 3.依次进行直至所有字符操作完毕
// 有括号:
// 1.扫描中缀表达式的每一个字符,将数字入列;
// 2.遇到运算符,栈空时直接进栈,栈顶非空时,运算符优先级大于栈顶元素才进栈,
// 否则栈顶元素退栈入列,当前运算符再进栈;
// 3.遇到左括号,直接进栈,左括号后面的运算符直接进栈,直至遇到右括号;
// 4.遇到右括号时,将栈顶元素依次退栈入列,直到遇到左括号,将左括号退栈,符号操作移动下一位
// 5.重复以上操作,直至所有字符操作完成。
public List<Arithmetic> infixToPostfix(){
        Stack<Arithmetic> stack = new Stack<>();
        List<Arithmetic> postfix = new ArrayList<>();
        for(int start = 0; start < infix.size(); start++){
            //如果是运算符
            if(infix.get(start).priority > 0) {
                //栈空 或 "(" 或 符号优先级>栈顶符号 且 不为")" 直接进栈
                if (stack.isEmpty() || infix.get(start).priority == 3 ||
                        ((infix.get(start).priority > stack.peek().priority) && infix.get(start).priority < 4)) {
                    stack.push(infix.get(start));
                } else if (!stack.isEmpty() && infix.get(start).priority <= stack.peek().priority) {
                    //栈非空 且 符号优先级≤栈顶符号, 出栈; 直到 栈为空 或 遇到了"("
                    while (!stack.isEmpty() && infix.get(start).priority <= stack.peek().priority) {
                        if (stack.peek().priority == 3) {
                            stack.pop();
                            break;
                        }
                        postfix.add(stack.pop());
                    }
                    stack.push(infix.get(start));
                } else if (infix.get(start).priority == 4) {
                    //")",依次出栈直到空栈或遇到第一个"(",此时"("出栈
                    while (!stack.isEmpty()) {
                        if (stack.peek().priority == 3) {
                            stack.pop();
                            break;
                        }
                        postfix.add(stack.pop());
                    }
 
                }
            }else if(infix.get(start).priority == -1){
                postfix.add(infix.get(start));
            }
        }
        while(!stack.isEmpty()){
            postfix.add(stack.pop());
        }
        return postfix;
    }
 

  

 

六、测试运行

1、测试用例

生成算式

 

 

 

 

七、项目小结

在这次结对编程的体验中,我负责测试及博客的编写,队友负责写算法及性能分析。我们采用一个人编程,一个人监督并帮忙的模式;达到一定时间角色互换,思维互换,这样既不会思维僵硬,还能学到对方身上的优点,还可以解决不专注问题。如果一个人编程感觉枯燥,进行不下去了,另一个就积极与她沟通,并帮忙编程。一开始,效果并不理想,我们两个的代码思路有分歧,但是在后面的开发过程中,我们不断沟通,借鉴前人的经验,出现了问题,一起想办法解决,包容不同的思想,从中获取经验,开发效率得到很大提高。在这个过程中,我们收获的不仅是编程能力的提高,更是团队协作,沟通能力和表达能力的提高。

 

标签:结对,编程,get,int,四则运算,List,运算符,30,new
From: https://www.cnblogs.com/hello-jame/p/17734256.html

相关文章

  • 结对项目
    软件工程班级链接作业要求结对项目github地址Github作业目标实现一个自动生成小学四则运算题目的程序姓名学号邓梓荣3121005121蔡嘉睿3121005159一、PSP表格PSP2.1PersonalSoftwareProcessStages预估耗时(分钟)实际耗时(分钟)......
  • 赛码网编程题--打字(Java全A)
    题目描述小明很喜欢打字,今天小红给了小明一个字符串。这个字符串只包含大写和小写字母。我们知道,按下CapsLock键,可以切换大小写模式。我们在小写模式时候,同时按下shift+字母键,就能写出大写字母。在大写模式的时候,按下shift+字母键,就能写出小写字母。现在问题来了,给你一个字符串,......
  • 结对项目壹(曾宇帆、陈年)
    -1作业概述|这个作业属于哪个课程|《软件工程》||----|----||这个作业要求在哪里|结对项目-作业-计科21级34班-班级博客-博客园(cnblogs.com)||这个作业的目标|实现一个自动生成小学四则运算题目的命令行程序||GitHub链接|https://github.com/guiwuwu/homework-3.git|......
  • 编程语言mojo报错:error: cannot call function that may raise in a context that can
    代码:frompythonimportPythonfnmain():#fnmain()raises:#ThisisequivalenttoPython's`importnumpyasnp`letnp=Python.import_module("numpy")leta=np.array([1,2,3])print(a) 运行报错:[02:19:48](mojo)dev......
  • 结对项目-四则运算题目生成
    前言这个作业属于哪个课程21计科三班这个作业要求在哪里结对项目这个作业的目标结对完成一个四则运算生成器及判题器,体验并熟悉结对编程的流程开发者黄锐智(3121005262)岑坤涛(3121005077)项目地址https://github.com/Taoika/Arithmetic已实现功能点使......
  • Java实现四则运算生成器
    这个作业属于哪个课程计科二班这个作业要求在哪里结对项目这个作业的目标熟悉结对编程项目成员龙新超3121004921github链接:龙新超github艾孜海尔江3121004900github链接:海尔江githubPSP表格PSP2.1PersonalSoftwareProcessStages预估耗时(分钟)实......
  • 结对项目
    作业概述这个作业属于哪个课程软件工程这个作业要求在哪里结对项目这个作业的目标和同伴共同合作完成项目成员曹富城学号:3121005076何继安学号:3121005087一、github链接https://github.com/flash2-man/calculatorhttps://github.com/muxingtong/MyCal......
  • socket 编程发送和接收缓存大小匹配问题
    socket编程中有发送、接收缓存的情况:例如服务器向客户端发送:105charserver_buf[BUF_SIZE]={0};123if(strncmp(server_buf,"exit",4)!=0)124{125printf("Servergot:%s\n",server_buf);126//将得到的字符串传给......
  • 面向对象编程的六大原则个人总结(附代码)
    面向对象编程的六大原则个人总结(附代码)目录面向对象编程的六大原则个人总结(附代码)一、什么是单一职责原则?核心思想好处代码示例总结二、什么是里式替换原则?规则代码示例总结三、什么是迪米特法则?核心思想规则代码示例总结四、什么是开闭原则?理解代码示例总结五、什么是依赖倒......
  • C# BeginInvoke实现异步编程
    C#BeginInvoke实现异步编程-CSDN博客https://blog.csdn.net/Nire_Yeyu/article/details/133203267 C#BeginInvoke实现异步编程BeginInvoke实现异步编程的三种模式:1.等待模式在发起了异步方法以及做了一些其他处理之后,原始线程就中断并且等异步方法完成之后再继续;eg:usingS......