zoukankan      html  css  js  c++  java
  • Java实现小学四则运算练习

     Github项目地址:https://github.com/feser-xuan/Arithmetic.git
    1、需求分析
       软件基本功能要求如下:
    • 程序可接收一个输入参数n,然后随机产生n道加减乘除练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间。
    • 为了让小学生得到充分锻炼,每个练习题至少要包含2种运算符。同时,由于小学生没有分数与负数的概念,你所出的练习题在运算过程中不得出现负数与非整数,比如不能出 3/5+2=2.6,2-5+10=7等算式。
    • 练习题生成好后,将你的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt中,不要输出额外信息文件目录与程序目录一致。
    • 当程序接收的参数为4时,以下为输出文件示例。
    • 软件附加功能要求如下:(请有余力的同学完成)
    • 支持有括号的运算式,包括出题与求解正确答案。注意,算式中存在的括号必须大于2个,且不得超过运算符的个数。
    • 扩展程序功能支持真分数的出题与运算,例如:1/6 + 1/8 + 2/3= 23/24。注意在实现本功能时,需支持运算时分数的自动化简,比如 1/2+1/6=2/3,而非4/6。

    2、功能分析

    • 使用Java中提供的Random类,随机产生0-100的正整数,并与随机产生的四则运算符号相结合,构成随机的四则运算。
    • 由于小学并没有接触到负整数,故随机计算结果为负的除去。
    • 当产生符合要求的四则运算题目时,计算正确答案并输出到名为result.txt的文件中。

    3、设计实现

    4、测试运行

    5、核心代码

    • 随机生成四则运算表达式:
     1             int[] number_temp = new int[rand.nextInt(2)+3];
     2             String[] str_temp = new String[number_temp.length-1];
     3             for(int i=0;i<number_temp.length;i++)
     4             {
     5                 if(i<number_temp.length-1)
     6                 {
     7                     number_temp[i]=rand.nextInt(100);
     8                     list_temp.add(String.valueOf(number_temp[i]));
     9                     str_temp[i]=operator[rand.nextInt(4)];
    10                     list_temp.add(str_temp[i]);
    11                     
    12                 }
    13                 else
    14                 {
    15                     number_temp[i]=rand.nextInt(100);
    16                     list_temp.add(String.valueOf(number_temp[i]));
    17                 }
    18             }
    • 用调度场算法产生逆波兰式:
    public static ArrayList<String> produce_RPN(ArrayList<String> list_temp)
        {
            int t=0,i=0;
            String tmp;
            Tack mytack = new Tack(20);
            ArrayList<String> lt_temp = new ArrayList<String>();
            while(true)
            {
                tmp = list_temp.get(i++);
                if(isInteger(tmp))
                {
                    lt_temp.add(tmp);
                }
                else{
                    if(mytack.myisempty())
                    {
                        mytack.mypush(tmp);
                    }
                        
                    
                    else{
                        if(isCPriority(tmp, mytack.mypeek()))
                            mytack.mypush(tmp);
                        else{
                            lt_temp.add(mytack.mypop());
                            mytack.mypush(tmp);
                        }
                        
                    }
                }
                if(i>=list_temp.size())
                {
                    while(!mytack.myisempty())
                        lt_temp.add(mytack.mypop());
                    System.out.println(transform_string(list_temp));
                    list_temp = lt_temp;
                    System.out.println(list_temp);
                    return list_temp;
                }
            }
            
            
        }
    • 用逆波兰式,计算表达式的结果:
    public static int calculate_RPN(ArrayList<String> list_temp)
        {
            int i=0,t;
            double a=0,b=0;
            String l_temp;
            Stack sk=new Stack(20);
            for(t=0;t<list_temp.size();t++)
            {
                l_temp = list_temp.get(i++);
                if(!isInteger(l_temp))
                {
                    b = sk.mypop();
                    a = sk.mypop();
                    switch(l_temp)
                    {
                    case "+":sk.mypush(a+b);break;
                    case "-":sk.mypush(a-b);break;
                    case "*":sk.mypush(a*b);break;
                    case "/":
                        if(b==0)
                            return -1;
                        sk.mypush(a/b);break;
                    }
                    System.out.println("st.mytop: "+sk.mypeek());
                }
                else{
                    sk.mypush((double)Integer.parseInt(l_temp));
                }
                
            }
            if(!sk.myisempty())
            {
                a = sk.mypop();
                b = a-(int)a;
                System.out.println("a:  "+a);
                if(a>0 && b==0 )
                {
                    return (int)a;
                }
                else
                    return -1;
            }
            else
                return -1;
            
        }
    • 当计算结果为正整数时,添加到数组list。反之则重复上述步骤:
           count=calculate_RPN(produce_RPN(list_temp));
                if(count !=-1)
                {
                    list_temp.add(" = "+count);
                    list.add(transform_string(list_temp));
                    number_n--;
                    list_temp.clear();
                }
                else
                    list_temp.clear();
    • 当产生适当符合要求的表达式时,现将自己的学号、姓名写到result.txt文件中,再将产生的表达式写到result.txt文件中:
    try {
            outSTr = new FileOutputStream(file1);
            Buff = new BufferedOutputStream(outSTr);
                try {
                    Buff.write("201571030104  丁炜轩".getBytes());
                    Buff.write("
    ".getBytes());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                for (int i = 0; i < list.size(); i++) 
                {
                    try {
                        Buff.write(list.get(i).getBytes());
                        Buff.write("
    ".getBytes());
                    } catch (IOException e) {
                        e.printStackTrace();
                        i--;
                    }
                }
            Buff.flush();
            Buff.close();
            
            } catch (IOException e) {
                e.printStackTrace();
            }
            //Buff.close();
            try {
                outSTr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
           
            for (int i = 0; i < list.size(); i++) 
            {
                System.out.print(list.get(i));
                System.out.println();
            }
            System.out.print("计算完毕!");
    • 到这时候,result.txt文件中已经就有了我们需要的四则运算表达式,以及正确的结果。
    • 还有几个小的函数,这里简单说一下:
    • 1.判断字符串是否为正整数:
    public static boolean isInteger(String str) {    
            for (int i = str.length();--i>=0;){  
                        if (!Character.isDigit(str.charAt(i))){
                            return false;
                        }
                    }
                    return true;
          } 
    • 2.判断运算符号的优先级顺序:
    public static boolean isCPriority(String str,String s) { 
            if((str+s).equals("*+") || (str+s).equals("*-") || (str+s).equals("/+") || (str+s).equals("/-"))
                return true;
            else
                return false;    
          }
    • 3.将动态数组转换为字符串类型:
    public static String transform_string(ArrayList<String> list_temp)
        {
            String s="";
            for(int i=0;i<list_temp.size();i++)
            {
                s+=list_temp.get(i);
            }
            return s;
            
        }
    • 在本次实验中,重要用到了栈:
    •  
       static class Stack
          {
              int mytop;
              double stk[];
              
              public Stack(int num) {
                  mytop=-1;
                  stk=new double[num];
              }
              /*出栈*/
              double mypop()
              {
                  double peek=stk[mytop];
                  mytop--;
                  return peek;
              }
              /*入栈*/
              void mypush(double x)
              {
                  mytop++;
                  stk[mytop]=x;
                  
              }
              /*判空*/
              Boolean myisempty()
              {
                  if(mytop==-1)
                      return true;
                  else
                      return false;
              }
              /*取栈顶元素*/
              double mypeek()
              {
                  double peek=stk[mytop];
                  return peek;
              }
              /*栈大小*/
              int mysize()
              {
                  return mytop+1;
              }
          }
          
          static class Tack
          {
              int mytop;
              String tk[];
              
              public Tack(int num) {
                  mytop=-1;
                  tk=new String[num];
              }
              /*出栈*/
              String mypop()
              {
                  String peek=tk[mytop];
                  mytop--;
                  return peek;
              }
              /*入栈*/
              void mypush(String x)
              {
                  mytop++;
                  tk[mytop]=x;
                  
              }
              /*判空*/
              Boolean myisempty()
              {
                  if(mytop==-1)
                      return true;
                  else
                      return false;
              }
              /*取栈顶元素*/
              String mypeek()
              {
                  String peek=tk[mytop];
                  return peek;
              }
              /*栈大小*/
              int mysize()
              {
                  return mytop+1;
              }
          }

     6、总结

       在本次实验中,主要在代码完成、调试中花了很多时间。我感觉一方面由于长时间不使用Java语言编写程序,对于Java语法结构、类的定义、函数的构造等知识方面都严重匮乏。一方面还是对于软件工程这门课理解略有偏差。不过在老师,以及助教老师的共同帮助下,我学到了一些书本上学不到的知识。值此,由衷的感谢老师们对于我的鼓励、帮助、以及肯定,我会继续发挥自己的长处,弥补自己不足的地方,为了祖国美好的明天,让我们共同努力!

    PSP2.1

    任务内容

    计划完成需要的时间(min)

    实际完成需要的时间(min)

    Planning

    计划

    30

    46

    ·       Estimate

    ·  估计这个任务需要多少时间,并规划大致工作步骤

    30

    46

    Development

    开发

    160

    200

    ··       Analysis

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

    20

    20

    ·       Design Spec

    ·  生成设计文档

    15

    20

    ·       Design Review

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

    5

    10

    ·       Coding Standard

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

    20

    20

    ·       Design

      具体设计

    30

    30

    ·       Coding

      具体编码

    60

    80

    ·       Code Review

    ·  代码复审

    5

    10

    ·       Test

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

    5

    10

    Reporting

    报告

    60

    80

    ··       Test Report

    ·  测试报告

    30

    40

    ·       Size Measurement

      计算工作量

    15

    20

    ·       Postmortem & Process Improvement Plan

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

    15

    20

  • 相关阅读:
    java Activiti 工作流引擎 SSM 框架模块设计方案
    自定义表单 Flowable 工作流 Springboot vue.js 前后分离 跨域 有代码生成器
    数据库设计的十个最佳实践
    activiti 汉化 stencilset.json 文件内容
    JAVA oa 办公系统模块 设计方案
    java 考试系统 在线学习 视频直播 人脸识别 springboot框架 前后分离 PC和手机端
    集成 nacos注册中心配置使用
    “感恩节 ”怼记
    仓颉编程语言的一点期望
    关于System.out.println()与System.out.print("\n")的区别
  • 原文地址:https://www.cnblogs.com/dwxuan/p/8613291.html
Copyright © 2011-2022 走看看