仿LSP运算

package 模拟考试2;

//仿LISP运算

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

/**
 类似符号运算, 用栈实现
  1.定义一个符号栈,和一个数字栈
  2. 遇到 "(" 和操作符, 入 符号栈
  3.遇到 数字, 检查连续数字,然后入数字栈
  4.遇到空格,不处理
  5.遇到 ")" ,出栈最后两个数字, 出栈最后一个运算符号,计算得到结果入数字栈, 然后出栈 "("一个
  6.遇到英文字母,即操作符号, 因为这几种操作符的开头都不一样,长度一样都是3,因此只要加入开头的字母就行,然后直接跳过2个  
  7. 计算结果如果 除0,输出error,退出
  8. 除法,向下取整

 */
public class Solution108 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String str = in.nextLine();
        Stack<Character> operator = new Stack<>();//符号栈
        Stack<Integer> numeric = new Stack<>(); //数字栈

        for (int i=0;i<str.length();i++) {
            char c=str.charAt(i);
            //如果是数字,需要连续判断。可能是负数
            if (Character.isDigit(c) ||c=='-'){
                StringBuilder builder = new StringBuilder();
                builder.append(c);
                i++;
                //判断连续数字
                while (i<str.length()){
                    char next=str.charAt(i);
                    if (Character.isDigit(next)){
                        builder.append(next);
                        i++;
                    }else {
                        break;
                    }
                }
                //因为重新进入for循环又会i++, 所以这里需要减回去
                i--;
                //加入数字栈
                numeric.push(Integer.valueOf(builder.toString()));
                //因为此时i 发生了变化,因此判断完连续数字,直接进入下一个循环
                continue;

                //如果是英文字母,即操作符号, 因为这几种操作符的开头都不一样,因此只要加入开头的字母就行,然后直接跳过2个
            }else if (Character.isLetter(c)){
                 operator.push(c);
                 i+=2;
                 continue;
                 //如果是左括号,直接入栈
            }else if (c=='('){
                operator.push('(');
            } else if (c==')'){ //出栈计算
                while (operator.peek()!='('){
                    //如果出现 除数为0异常,直接退出
                     if (!calculator(operator,numeric)){
                         return;
                     }
                }
                //最后要把一个 "(" 出栈
                operator.pop();
            }else {
                //空格,不处理
            }
        }
        //最后处理操作符栈剩下的
        while (numeric.size()>1){
            if (!calculator(operator,numeric)) {
                return;
            }
        }
        System.out.println(numeric.peek());
    }

    public static boolean calculator(Stack<Character> operator,Stack<Integer> numeric){
        Character op = operator.pop();
        Integer two = numeric.pop();
        Integer one = numeric.pop();
        //如果是除法,除数不能为0
        if (op=='d'&&two==0){
            System.out.println("error");
            return false;
        }
        int res=count(one,two,op);
        //结果入栈
        numeric.push(res);
        return true;
    }


    //计算结果
    public static int count(int a,int b,char op){
        int res=0;
       switch (op){
           case 'm':  //乘法
               res=a*b;
               break;
           case 'a':  //加法
               res=a+b;
               break;
           case 's': //减法
               res=a-b;
               break;
           case 'd': //除法  -4 5
               //向下取整,  例如 div 1 -4 =-0.25向下取整为-1
               res = (int) Math.floor(a / (b + 0.0));
               break;
       }
       return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值