2018-2019-2 《Java程序设计》结对项目阶段总结《四则运算——整数》

20175218 2018-2019-2 《Java程序设计》结对项目阶段总结《四则运算——整数》

1、需求分析

实现一个命令行程序,要求:java

  • 自动生成小学四则运算题目(加,减,乘,除)
    • 文本支持整数
    • 支持多运算符(例如生成包含n个运算符的题目)
    • 支持真分数(后续实现)
  • 统计正确率

扩展需求git

  • 文件:
    • 处理生成题目并输出到文件
    • 完成题目后从文件读入并判断
  • 多语言支持:简体中文,繁體中文,English
  • 生成题目去重

2、设计思路以及代码解释

最开始看到这个结对项目的时候,我以为,最为第一个项目,应该不会很难。而在真正看到项目的时候,也感受不是很难。在这一点上,我和个人搭档是同一个想法,都以为还行。可是越是日后作,就愈加现,这怎么这么复杂...其实,是这样的,最开始,咱们没有考虑到括号、运算优先级以及多个数字运算的问题,就只是简单设计了一个两个数字简单的四则运算,这个程序呢,我也发出来了,以下:编程

//生成随机整数的运算数组

public class Zheng {
        int a=0,b=0,c=0;
    int result=0,g=0;
    String s=null;
    public void Zheng(){
        a = (int)(Math.random()*100);//生成0-99的随机数
        b = (int)(Math.random()*100);
        c = (int)(Math.random()*4);//生成0-3的随机数,用来随机产生运算符
         if(c==0){
             System.out.println(a+"+"+b+"=");
             result = a + b;
         }
         if(c==1){
                         System.out.println(a+"-"+b+"=");
             result = a - b;
         }
                 if(c==2){
                         System.out.println(a+"*"+b+"=");
             result = a * b;
        }
                 if(c==3){
                      if(b==0){
                             while(b==0) 
                             b=(int)(Math.random()*10);//防止分母为0
            }
                      else{ 
                         System.out.println(a+"/"+b+"=");
                         int smaller = a > b ? b : a;//将a与b中的最小值赋给变量
                         for (int i = 1; i <= smaller; i++) {
                 if (a % i == 0 && b % i == 0) {
                     g = i;
                 }//求a与b的最大公因子
             }
             a = a/g;
             b = b/g;
             s = a+"/"+b;
        }   
    }
  } 
}

//实现四则运算dom

import java.util.*;
public class YunSuan {
    public static void main (String args[]){
        int x,z=0;
        Zheng zheng = new Zheng();
        System.out.print("请输入要生成的题目数:");
        Scanner reader = new Scanner(System.in);
        int n = reader.nextInt();
        Random random = new Random();
        for(int i=1;i<n+1;i++){
        for(;;){
            System.out.println("题目"+i+":");
            zheng.Zheng();
            System.out.print("请输入结果:");
            if(zheng.c==3){
                Scanner sc=new Scanner(System.in);
                String s =new String();
                    s =sc.nextLine();
                if(s.equals(zheng.s)){
                    z++;
                    System.out.println("此题正确");
            }
                    else
                        System.out.println("此题错误,正确答案为:"+zheng.s);
            }
            else{
            x =reader.nextInt();
            if(x==zheng.result){
                z++;
                    System.out.println("此题正确");
            }
            else
                System.out.println("此题错误,正确答案为:"+zheng.result);
            
            }
                break;
              }
            }
        int o =(int)(((double)z/(double)n)*100);//计算正确率
            System.out.print("完成"+n+"道题,正确数目为:"+z+",正确率为:");
        System.out.printf("%d",o);
        System.out.println("%");
    }
}

四则运算简版连接:码云连接命令行

然后来作的过程当中,发现不只仅是这么简单,咱们须要考虑到不少东西,包括括号、运算优先级以及多个数字计算的因素等。因而咱们卡在这里好长时间,特别是在作栈以及中缀转后缀这块时,咱们不知道该如何作下去了。而后咱们就查资料以及加上咱们两我的的共同思考,终于知道了如何解决括号与计算问题,经过一段时间的努力,最终得出了代码。然而,依旧不是这么简单,咱们的代码仍是有一些问题,代码以下:设计

//生成随机数code

import java.util.*;
public class RandomNum {
    int RandomNum(int x){
        int num =(int)(Math.random()*x);
        return num;
    }
}

//生成随机运算符
import java.util.*;
public class RandomChar {
     char RandomChar(){
        int num = (int)(Math.random()*4);
        switch (num){
            case 0:return'+';
            case 1:return'-';
            case 2:return'*';
            case 3:return'÷';
            default:return 0;
        }
    }
}

//生成中缀表达式以及产生题目blog

import java.util.*;
public class Produce {
    void Produce(int n){
        RandomNum num = new RandomNum();
        RandomChar c = new RandomChar();
        Scanner reader = new Scanner(System.in);
        String s = "";
        String d = "";
        String g = "";
        String out = "";//最终的中缀表达式
        String end = "";//转化后的后缀表达式
        int count = 0;//记录作对的题目个数
            for(int i=1;i<n+1;i++){
            System.out.println("题目"+i+":");
            int a = (int)(Math.random()*5+1);
                int amount = num.RandomNum(a)+1;//记录随机产生运算符的个数
            for(int j=0;j<amount;j++){
            s = s+c.RandomChar()+" ";
            }
            String str[] = s.split(" ");//将字符串转化成字符串数组
            for(int z=0;z<str.length;z++){
                d = d+num.RandomNum(50)+str[z];
            }
            d = d + num.RandomNum(50);
            switch((num.RandomNum(2))){
                case 0:
                    System.out.println(d+" = ");//输出不带括号的中缀表达式
                    break;
                case 1:
                        for(int k=0;k<str.length;k++){
                           g = num.RandomNum(50)+ str[num.RandomNum(str.length-1)] + "(" + num.RandomNum(50) + str[num.RandomNum(str.length-1)] + num.RandomNum(50) + ")" + str[k];
                    }//在中缀表达式中加入括号
                    g = g + num.RandomNum(50);
                    System.out.println(g+" = ");//输出不带括号的中缀表达式
                                        break;

            }
            out = g;
            out = d;
            int p = 0;//初始化最终获得的答案
            infixToSuffix in = new infixToSuffix();
            end = in.infixToSuffix(out);//将中缀表达式转化为后缀表达式
            suffixToArithmetic ex = new suffixToArithmetic();
            p = (int) ex.suffixToArithmetic(end);//计算后缀表达式的结果
                System.out.print("请输入结果:");
            int x = reader.nextInt();
            if(x==p){
                System.out.println("结果正确!");
                count++;
            }
            else{
                System.out.println("结果错误,正确结果是:"+p);
            }
            s="";
            g="";
            d="";
        }
        int result = (int)(((double)count/(double)n)*100);//计算正确率
        System.out.println("总共答题"+n+"道,正确率为:"+result+"%");
    }
    
}

//将中缀表达式转化为后缀表达式队列

import java.util.*;
public class infixToSuffix {
public static String infixToSuffix(String infix) {
        Stack<Character> stack = new Stack<Character>();
        String suffix = "";
        int length = infix.length();
        for (int i = 0; i < length; i++) {
            Character temp;
            char c = infix.charAt(i);
            switch (c) {
                // 忽略空格
                case ' ':
                    break;
                // 碰到'(',push到栈
                case '(':
                    stack.push(c);
                    break;
                // 碰到'+''-',将栈中全部运算符弹出,送到输出队列中
                case '+':
                case '-':
                    while (stack.size() != 0) {
                        temp = stack.pop();
                        if (temp == '(') {
                            stack.push('(');
                            break;
                        }
                        suffix += " " + temp;
                    }
                    stack.push(c);
                    suffix += " ";
                    break;
                // 碰到'*''/',将栈中全部乘除运算符弹出,送到输出队列中
                case '*':
                case '/':
                    while (stack.size() != 0) {
                        temp = stack.pop();
                        if (temp == '(' || temp == '+' || temp == '-') {
                            stack.push(temp);
                            break;
                        } else {
                            suffix += " " + temp;
                        }
                    }
                    stack.push(c);
                    suffix += " ";
                    break;
                // 碰到右括号,将靠近栈顶的第一个左括号上面的运算符所有依次弹出,送至输出队列后,再丢弃左括号
                case ')':
                    while (stack.size() != 0) {
                        temp = stack.pop();
                        if (temp == '(')
                            break;
                        else
                            suffix += " " + temp;
                    }
                    // suffix += " ";
                    break;
                //若是是数字,直接送至输出序列
                default:
                    suffix += c;
            }
        }

        //若是栈不为空,把剩余的运算符依次弹出,送至输出序列。
        while (stack.size() != 0) {
            suffix += " " + stack.pop();
        }
        return suffix;
    }
}

//计算后缀表达式的值

import java.util.*;
public class suffixToArithmetic{
    int suffixToArithmetic(String h) {
        Stack<Integer>stack = new Stack<Integer>();
        String b[] = h.split(" ");//将字符串转化为字符串数组
        for(int i=0;i<b.length;i++){
            String c = b[i];
            if((c.equals("+")||c.equals("-"))||(c.equals("*")||c.equals("÷"))){
                int y = stack.pop();
                int x = stack.pop();
                Caculate z = new Caculate();
                                stack.push(z.Caculate(x,y,c));//将运算结果从新压入栈
            }//是运算符,弹出运算数,计算结果
            else{
                stack.push(Integer.valueOf(c));
            }
        }
        return stack.pop();//弹出栈顶元素就是运算最终结果
    }
}

//断定运算符并进行运算

class Caculate{
    int Caculate(int x,int y,String c) {
        if (c.equals("+"))
            return x + y;
        if (c.equals("-"))
            return x - y;
        if (c.equals("*"))
            return x * y;
        if (c.equals("/")){
        if(x<=y||x==0) return 1;
        else return x / y;
    }
    return 0;
    }
}

四则运算连接:码云连接

3、总结分析与运行截图

结对项目总结与分析

咱们开始的时候,都没有太注重这个项目,以为它不难。可是在作起这个项目时,咱们就发现本身错了————这个项目并不简单。相反,它仍是很复杂的。这也让咱们知道了为什么它是结对项目了,而不是我的项目。在作这个项目的时候,咱们遇到最大的问题就是缺乏这一块的知识,因此咱们不得不边学边作。所以,在编程中咱们遇到了不少问题,包括往中缀表达式加入括号的问题,以及除法计算的问题,遇到左右括号数量不等的状况,遇到括号只括住一个数字或者一个运算符的问题,遇到碰见除法没法输出的问题,遇到没法计算出结果的问题。幸亏,个人搭档很是厉害,这些大多数都是个人搭档张智敏解决的,可是依旧有个问题没有解决,就是除法计算问题:
截图

(关于UML图,咱们暂时还未弄好,在后面的结对项目中咱们会补上)

代码运行截图

四则运算简版运行截图:

四则运算运行截图:

4、结对同伴的评价

在此次项目中,个人搭档张智敏同窗是驾驶员的身份,而我是领航员的身份。在此次项目中,个人搭档充分体现了驾驶员的身份,全部代码都是他操控键盘打出来的。而且在遇到问题的时候,他都分析得很仔细认真,因此大多数问题都是他先想出解决办法并最后解决的,因此我认为个人搭档很是棒。在之后的项目中,咱们会合做得更好,但愿我能帮到个人搭档更多,争取把咱们的项目作得更好。

5、代码托管

代码托管

相关文章
相关标签/搜索