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

  • 相关阅读:
    求字符串中最大的递增子序列
    分析函数改写自关联
    收集统计信息让SQL走正确的执行计划
    利用case when 减少表扫描次数
    利用查询提示优化SQL
    利用SQL进行推理
    查找字段连续相同的最大值
    优化有标量子查询的SQL
    将部分相同的多行记录转成一行多列
    .net 测试工具类
  • 原文地址:https://www.cnblogs.com/dwxuan/p/8613291.html
Copyright © 2011-2022 走看看