zoukankan      html  css  js  c++  java
  • 结对作业-四则运算升级版

    第一阶段目标:重构四则运算-- 能把计算的功能封装起来,通过API 接口调用计算方法。
    定义一个计算核心类:把四则运算的计算功能包装在一个模块中 (这个模块可以是一个类 Class,  一个DLL等等)。
     “计算核心”模块和调用类它的其他模块之间是什么关系呢?  
    它们要通过一定的API (Application Programming Interface) 来和其他模块交流。
    这个API 接口应该怎么设计呢? 可以从下面的最简单的接口开始:
    Calc()
    这个Calc 函数接受字符串的输入(字符串里就是运算式子,例如 “ 5+3.5“,  “7/8 – 3/8 ”,  “3 + 90 * (-0.3)“  等等),这个模块的返回值是一个字符串,例如,前面几个例子的结果就是 ( ”17.5“, “ 1/2”, “-24“).

    package com.az.test.calc;
    import java.util.Scanner;
    import com.az.test.calc.CreateShiZi;
    import com.az.test.calc.NiBoLanShi;
    public class Student {
    public static void main(String[] args) {
    CreateShiZi createShiZi = new CreateShiZi();
    NiBoLanShi niBoLanShi = new NiBoLanShi();
    String[] fuHao = {"+","-","*","/"};
    Scanner input = new Scanner(System.in);
    System.out.println("请输入范围内的计算:");
    int m = input.nextInt();
    System.out.println("请输入要产生的题数:");
    int n = input.nextInt();
    String[] strArray = new String[n];
    System.out.println("
    题目
    ");
    createShiZi.create(m, n, fuHao, strArray);
    for(int i = 0; i<n; i++) {
    String result = niBoLanShi.cal(strArray[i]);
    System.out.println("第"+(i+1)+"题:"+strArray[i]);
    System.out.print("你的答案:");
    String yourAnswer = input.next();
    if (yourAnswer.equals(result)) {
    System.out.println("True
    ");
    }else {
    System.out.println("False");
    System.out.println("正确答案:"+result+"
    ");
    }
    }
    }
    }
    package com.az.test.calc;
    import java.util.List;
    import java.math.BigDecimal;
    import java.util.ArrayList;
    import java.util.Stack;
    public class NiBoLanShi {
    public static String cal(String str) {
    //对表达式进行预处理,并简单验证是否是正确的表达式
    //存放处理后的表达式
    List<String> list = new ArrayList<>();
    char[] arr = str.toCharArray();
    
    //存放数字临时变量
    StringBuffer tmpStr = new StringBuffer();
    for (char c : arr) {
    //如果是数字或小数点,添加到临时变量中
    if (c>='0' && c<='9') {
    tmpStr.append(c);
    }else if(c=='.') {
    if(tmpStr.indexOf(".")>0) {
    throw new RuntimeException("非法字符");
    }
    tmpStr.append(c);
    }
    
    //如果是加减乘除或者括号,将数字临时变量和运算符依次放入List中
    else if (c=='+' || c=='-' || c=='*' || c=='/' || c=='(' || c==')') {
    if (tmpStr.length() > 0) {
    list.add(tmpStr.toString());
    tmpStr.setLength(0);
    }
    list.add(c + "");
    }
    else if (c==' ') {
    continue;
    }
    else {
    throw new RuntimeException("非法字符");
    }
    }
    if (tmpStr.length() > 0) {
    list.add(tmpStr.toString());
    }
    
    //初始化后缀表达式
    List<String> strList = new ArrayList<>();
    
    //运算过程中,使用了两次栈结构,
    //第一次是将中缀表达式转换成后缀表达式,第二次是计算后缀表达式的值
    Stack<String> stack = new Stack<>();
    
    //声明临时变量,存放栈元素
    String tmp;
    
    //将中缀表达式转换成后缀表达式
    for (String s : list) {
    //如果是左括号直接入栈
    if (s.equals("(")) {
    stack.push(s);
    }
    
    //如果是右括号,执行出栈操作,依次添加到后缀表达式中,直到出栈元素为左括号,左括号和右括号都不添加到后缀表达式中
    else if (s.equals(")")) {
    while (!(tmp = stack.pop()).equals("(")) {
    strList.add(tmp); 
    }
    }
    
    //如果是加减乘除,弹出所遇优先级大于或等于该运算符的栈顶元素(栈中肯定没有右括号,认为左括号的优先级最低),然后将该运算符入栈
    else if (s.equals("*") || s.equals("/")) {
    while(!stack.isEmpty()) {
    //取出栈顶元素
    tmp = stack.peek();//取出但不移除
    if (tmp.equals("*") || tmp.equals("/")) {
    stack.pop();
    strList.add(tmp);
    }
    else {
    break;
    }
    }
    stack.push(s);
    }
    else if (s.equals("+") || s.equals("-")) {
    while(!stack.isEmpty()) {
    //取出栈顶元素
    tmp = stack.peek();
    if (!tmp.equals("(")) {
    stack.pop();
    strList.add(tmp);
    }
    else {
    break;
    }
    }
    stack.push(s);
    }
    
    //如果是数字,直接添加到后缀表达式中
    else {
    strList.add(s);
    }
    }
    
    //最后依次出栈,放入后缀表达式中
    while (!stack.isEmpty()) {
    strList.add(stack.pop());
    }
    
    //计算后缀表达式的值
    Stack<BigDecimal> newStack = new Stack<>();
    for (String s : strList) {
    //若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的放到运算符的左边
    //运算后的结果再进栈,直到后缀表达式遍历完毕
    if (s.equals("*") || s.equals("/") || s.equals("+") || s.equals("-")) {
    BigDecimal b1 = newStack.pop();
    BigDecimal b2 = newStack.pop();
    switch (s) {
    case "+":
    newStack.push(b2.add(b1));
    break;
    case "-":
    newStack.push(b2.subtract(b1));
    break;
    case "*":
    newStack.push(b2.multiply(b1));
    break;
    case "/":
    newStack.push(b2.divide(b1, 9, BigDecimal.ROUND_HALF_UP));
    break;
    }
    }
    
    //如果是数字,入栈
    else {
    newStack.push(new BigDecimal(s));
    }
    }
    
    //最后,栈中仅有一个元素,就是计算结果
    return newStack.peek().toString();
    }
    }
    package com.az.test.calc;
    
    public class CreateShiZi {
    public void create(int m, int n, String[] fuHao, String[] strArray) {
    String str = "";
    
    //随机生成式子
    for (int i = 0; i < n; i++) {
    str = "";
    int[] arr1 = new int[n];
    int[] arr2 = new int[n];
    arr2[i] = (int)(Math.random()*m+1);
    for(int j = 0; j < (int)(Math.random()*10+1); j++) {
    int order = (int)(Math.random()*4);
    arr1[j] = (int)(Math.random()*m+1);
    str = str + arr1[j] + fuHao[order];
    }
    str = str + arr2[i];
    strArray[i] = str;
    System.out.println("第"+(i+1)+"题:"+str);
    arr1 = null;
    arr2 = null;
    }
    System.out.println("
    ");
    }
    }
    
  • 相关阅读:
    ubuntu12.04 死机 卡屏 画面冻结解决方案
    Install Firefox 20 in Ubuntu 13.04, Ubuntu 12.10, Ubuntu 12.04, Linux Mint 14 and Linux Mint 13 by PPA
    ListView1.SelectedItems.Clear()
    android studio 下载地址
    jquery.slider.js jquery幻灯片测试
    jquery.hovermenu.js
    jquery.tab.js选项卡效果
    适配 placeholder,jquery版
    jquery.autoscroll.js jquery自动滚动效果
    将 Google Earth 地图集成到自己的窗体上的 简单控件
  • 原文地址:https://www.cnblogs.com/zhjvvvvvv/p/13088167.html
Copyright © 2011-2022 走看看