HDU1237简单计算器

读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。

Input
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。

Output
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。

Sample Input
1 + 2
4 + 2 * 5 - 7 / 11
0

Sample Output
3.00
13.36

这是一个简单的计算器。下面我自己讲一下原理吧。简单的来说就是弄两个栈一个用来存数值,一个用来存加减乘除的符号。你也可以用数组来做,不过JAVA自己自带栈的功能,用起来会方便很多。

值得注意的是:用来装数值的栈,最多存两个数值,这是为了计算。而装符号的则是装一个。当我们遇到’ *’ 和’/‘时,我们是先进行运算,再压栈。对了,在写运算函数时一定要注意,运算的顺序,我自己写的时候,因为大意,也是被坑了很久。
具体代码如下:
package Temp;

import java.util.Scanner;
import java.util.Stack;

public class P1237 {

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    String str = sc.nextLine();

    while (!str.equals("0")) {// 到0了就结束 用栈来做
        Stack<Double> num = new Stack<Double>();// 加数值
        Stack<Character> md = new Stack<Character>();// 加运算符“+”,“-”,“*”,“/"

        String str1[] = str.split(" ");// 用一个新的数组,以空格来划分

        for (int i = 0; i < str1.length; i++) {
            if (isNumber(str1[i])) {// 如果是数字就加栈
                double d = Double.parseDouble(str1[i]);
                if (num.size() <= 1) {// 最少能放俩个数字进去
                    num.push(d);
                }
            } else {
                if (md.isEmpty()) {// 如果加字符的为空就加入进去
                    md.push((str1[i]).charAt(0));
                } else {
                    char md1 = md.peek();// 看栈的顶层是什么符号
                    char md2 = str1[i].charAt(0);// i i的符号

                    /*
                     * 下面自己写个函数来根据返回值来判断,先运行什么符号
                     */
                    if (opration(md1, md2) <= 1) {
                        double nextNum = num.pop();// 进行弹栈来运算//代表栈的顶端
                        double lastNum = num.pop();// 代表栈的底端

                        // 因为是小于等于一所以先把MD中的符号弹栈,再把后面的符号压栈,再把结果放入num中
                        num.push(math(lastNum, nextNum, md.pop()));
                        md.push(str1[i].charAt(0));
                        /* 可以不要 */

                        // } else if (opration(md1, md2) == 2// 判断下一个符号
                        // && i + 2 < str1.length
                        // && opration((str1[i + 2]).charAt(0), md2) != 1) {
                        // double nextNum = Double.valueOf(str1[i + 1]);
                        // double lastNum = num.pop();

                        // num.push(math(nextNum, lastNum, md2));
                    } else if (opration(md1, md2) == 2) {
                        double nextNum = Double.valueOf(str1[++i]);// 获得下一个
                        double lastNum = num.pop();
                        num.push(math(lastNum, nextNum, md2));
                    }
                }
            }
        }
        if (!md.empty()) {// 运算符栈中不空的话,数值栈中一定有俩个数值
            double nextNum = num.pop();
            double lastNum = num.pop();
            // System.out.printf("%.2f", math(lastNum, nextNum, md.pop()));
            System.out.println(String.format("%.2f",
                    math(lastNum, nextNum, md.pop())));
        } else if (num.size() == 1) {
            // System.out.printf("%.2f\n", num.pop());
            System.out.println(String.format("%.2f", num.pop()));
        }
        str = sc.nextLine();// 获取下一个运算
    }
}

private static Double math(double num1, double num2, Character pop) {
    // 用swith case来进行匹配运算
    switch (pop) {
    case '+':
        return (num1 + num2);
    case '-':
        return num1 - num2;
    case '*':
        return num1 * num2;
    case '/':
        return num1 / num2;
    }
    return (double) 0;

}

private static int opration(char md1, char md2) {
    if (md1 == '*' || md1 == '/') {
        if (md2 == '*' || md2 == '/') {
            return 0;// 如果两个都是乘法或者除法那么运算顺序是一样的
        } else
            return 1;// 那先运行md1
    } else {
        if (md2 == '*' || md2 == '/') {
            return 2;// 先运行md2
        }

    }
    return 0;// 都是加加减法顺序一样
}

// 判断是否是数字
private static boolean isNumber(String str) {
    char ch[] = str.toCharArray();
    for (int i = 0; i < str.length(); i++) {
        if (ch[i] < 48 || ch[i] > 57) {
            return false;
        }
    }
    return true;
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值