zoukankan      html  css  js  c++  java
  • PSP流程下四则运算升级

    PSP流程下四则运算升级

     

    一、需求分析

    1.输入参数n,随机产生n道加减乘除

    2.数字在1-100,运算符3-5个

    3.无负数和非整数

    4.一个算式最少两种运算符

    5.附带学号输出result.txt文件

     

    二、功能设计

    基本功能:四则运算,随机产生n道算式

    扩展功能:能够计算括号

     

    三、设计实现

    1.项目目录

    img

    我希望通过四个类来实现所有功能

    Main为主函数,负责作为输入和运行的入口 dateFile为辅助,用于进行文件创建和读写 random为辅助,用于产生随机的算式 caculate为核心,用于计算随机产生的算式并返回结果 2.整体思路:

    1)先生成随机生成一个运算符和两个运算数的算式,进行结果运算,查看是否符号无负数和无小数的要求。在满足要求后,将该算式结果作为下一次生成算式的因子,用连接符再进一步连接,直到组成3-5个运算符的算式(随机生成的工作结束,输出一个字符串)

    2)通过逆波兰表达式,对产生的字符串进行解析计算

     

    四、算法详情

    1.随机生成算式

    static String[] symAll = { "+", "-", "*", "÷" };// 设置操作符的集合
    static String[] sym = { "+", "*" };// 连接两个简单等式时的操作符
    static int flag = 0;// 标记简单等式产生减号或加号的情况,由此确定是否生成括号
       int ifsame=0;//判断符号相同
       int answer=0;//判断为非负
    public static String make() {
    int x = (int)(Math.random()*101);
           int y = (int)(Math.random()*101);
           int z = (int)(Math.random()*4);
           if(z==1) {
          if(x<y) {
          int temp=x;
          x=y;
          y=temp;
          }
          }
           if(z==3) {
          y = (int) (Math.random() * 20) + 1;
    x = (int) (Math.random() * 6) * y;
          }
           String str = x + symAll[z] + y;
    if (symAll[z].equals("-") || symAll[z].equals("+")) {// 减号时使flag等于1
    flag = 1;

    }
    return str;

     

    2.解答算式的算法

    首先,将字符串通过substring进行逐个提取,每一个进行检验,从左到右将数字和符号分开

    之后,设置两个栈,一个用于放置操作符,一个用于放置结果

    Stack<String>symbolStack = new Stack<String>();//放置操作符的栈
    Stack<String>numberStack = new Stack<String>();//放置最后结果的栈
    Iterator<String>iter = list.iterator();
    while(iter.hasNext()) {
    String listItem = iter.next();//分开放置
    //检测是否为符号
    if(isSymbol(listItem)) {
    //当检测到),需要一直出栈,直到检测到(,该过程中还需要检测栈空
    if(")".equals(listItem)) {
    while (!(symbolStack.isEmpty() || "(".equals(symbolStack.peek()))){
    numberStack.push(symbolStack.pop());//操作符栈的栈顶元素进入结果栈
    }
    //当检测到(
    if(!symbolStack.isEmpty() && "(".equals(symbolStack.peek())) {
    symbolStack.pop();
    }else {
    throw new Exception("异常");
    }
    }
    //当检测到(,直接入栈
    else if("(".equals(listItem)) {
    symbolStack.push(listItem);
    }
    //当遇到除(、)之外的运算符,则对运算符优先级进行比较,高则入栈,反之出栈并进入结果栈
    else {
    while (!(symbolStack.isEmpty() || "(".equals(symbolStack.peek()))) {
    if(compareSymbol(listItem,symbolStack.peek())<1) {
    numberStack.push(symbolStack.pop());
    }else {
    break;
    }
    }
    symbolStack.push(listItem);
    }
    }
    //非操作符,入栈操作
    else {
    numberStack.push(listItem);
    }
    }

    当检测到)时,则把操作符栈弹出,并且置入最后结果的栈中,直到遇到(停止

    当检测到(时,直接进入操作符栈

    当检测到其他操作符,与栈顶运算符比较,如果比栈顶等级高,则进入操作符栈

    否则操作符栈弹出,并且置入结果栈,再重复以上操作

     

    最后,将符号栈中的元素全部置入结果栈中。因为栈是先进后出,所以还需要逆序遍历之后,得到最后的后缀表达式

    对后缀表达式求值

    private static int finalCalculate(List<String> finalList) {
    Stack<Integer> answerStack = new Stack<Integer>();
    Iterator<String>iter = finalList.iterator();
    int x,y;
    while(iter.hasNext()) {
    String answerItem = iter.next();
    if(isSymbol(answerItem)) {
    x = answerStack.pop();
    y = answerStack.pop();
    answerStack.push(calculate(y,x,answerItem));
    // System.out.println(answerStack);
    }
    else {
    answerStack.push(Integer.parseInt(answerItem));
    // System.out.println(answerStack);
    }
    }
    // System.out.println(answerStack);
    return answerStack.pop();

    五、测试运行

    img

     

  • 相关阅读:
    我的浏览器收藏夹分类
    我的浏览器收藏夹分类
    Java实现 LeetCode 318 最大单词长度乘积
    Java实现 LeetCode 318 最大单词长度乘积
    Java实现 LeetCode 318 最大单词长度乘积
    Java实现 LeetCode 316 去除重复字母
    Java实现 LeetCode 316 去除重复字母
    Java实现 LeetCode 316 去除重复字母
    Java实现 LeetCode 315 计算右侧小于当前元素的个数
    Java实现 LeetCode 315 计算右侧小于当前元素的个数
  • 原文地址:https://www.cnblogs.com/satoshi3104/p/15310701.html
Copyright © 2011-2022 走看看