四则运算 不含小数

题目描述:

输入: 字符串格式的算术表达式,如: “3+2*{1+2*[-4/(8-6)+7]}”, 数字部分无小数
输出: 计算结果

思路: 使用两个栈, 一个保存运算符, 一个保存数字
这个题目主要是各类特殊情况需要考虑比较多

java代码实现:

import java.util.*;
@SuppressWarnings("unchecked")
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String str = sc.nextLine();
            Stack sn = new Stack();
            Stack so = new Stack();
            so.push('(');
            str = str +")";
            for(int i = 0; i<str.length(); i++){
                char ch = str.charAt(i);

                /***数字部分开始***/
                int tmpInt = 0;
                boolean isDigit = false;
                // 循环处理多位数
                while(isDigit(ch)){
                    tmpInt = tmpInt*10 + (ch-'0');
                    i++;
                    ch = str.charAt(i);
                    isDigit = true;
                }
                if(isDigit){
                    i--; //多位数字最后一次i++回退
                    sn.push(tmpInt);
                    continue;
                }
                /***数字部分开始***/

                /***运算符部分开始***/
                // 如果是(则直接压入so
                if(isEqualLeft(ch)){
                    so.push('(');
                    continue;
                }
                // 处理负号, 转换为0-x的样式, 负号前面不能为数字或者右括号; 考虑特殊情况, 第一个数字是负数(牛客网上面这一题测试用例没考虑到这个情况)
                if(ch == '-' && (((i-1)>=0 && !isDigit(str.charAt(i-1)) && !isEqualRight(str.charAt(i-1))) || i==0)){
                    sn.push(0);
                }
                char ch1 = (char)so.peek();
                // 大于前一个运算符优先级 或者 前面的数字少于2个(无法凑出一次运算), 则直接推入运算符
                if(isPriority(ch1, ch) || sn.size()<2){
                    so.push(ch);
                }else{
                    if(isEqualRight(ch)){
                        handleCal(sn, so, ch);
                        if(!so.isEmpty() && isEqualLeft((char)so.peek())){
                            so.pop();
                        }
                    }else{
                        handleCal(sn, so, ch);
                        so.push(ch);
                    }
                }
                /***运算符部分结束***/
            }
            System.out.println(sn.pop());
        }
    }

    private static boolean isEqualLeft(char ch){
        if(ch == '(' || ch == '{' || ch == '['){
            return true;
        }
        return false;
    }

    private static boolean isEqualRight(char ch){
        if(ch == ')' || ch == '}' || ch == ']'){
            return true;
        }
        return false;
    }

    private static void handleCal(Stack sn, Stack so, char ch){
        while(!so.isEmpty() && !isEqualLeft((char)so.peek()) && !isPriority((char)so.peek(),ch)){
            int valb = (int)sn.pop();
            int vala = (int)sn.pop();
            char op = (char)so.pop();
            int res = calculateVal(vala, valb, op);
            sn.push(res);
        }
    }

    private static int calculateVal(int vala, int valb, char op){
        if(op == '+'){
            return vala + valb;
        }
        if(op == '-'){
            return vala - valb;
        }
        if(op == '*'){
            return vala * valb;
        }
        if(op == '/'){
            return vala / valb;
        }
        return 0;
    }

    private static boolean isDigit(char ch){
        if(ch<='9' && ch>='0'){
            return true;
        }
        return false;
    }

    private static boolean isPriority(char ch1, char ch2){
        if(ch2 == ')'){
            return false;
        }
        if((ch2 == '*' || ch2 == '/') && (ch1 == '+' || ch1 == '-')){
            return true;
        }
        return false;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值