栈:综合计算器案例

问题背景:使用栈来模拟表达式计算,比如计算字符串String data = "13+10*3-2"的值。

使用栈完成表达式计算的思路分析:

  1. 遍历表达式,将字符串按照字符数组来操作;
  2. 如果遍历到的字符是数字,就直接压入数字栈中;
  3. 如果遍历到的字符是符号,判断操作符栈是否为空;
  4. 如果操作符栈为空:直接将该字符压入操作符栈中;
  5. 如果操作符栈不为空,那么判断操作符的优先级(自定义优先级);
  6. 如果操作符的优先级比当前栈顶元素的优先级高,直接压入操作符栈;
  7. 如果操作符的优先级比当前栈顶元素的优先级,那么数字栈中弹出两个数字,同时操作符栈弹出一个栈顶元素,从而组合成一个计算式,将计算式的结果压入数字栈中,注意此时的操作符压入操作符栈
  8. 遍历完所有的字符之后,按照顺序从数字栈和操作符栈弹出对应的数和符号,计算出结果并压入数字栈,直到数字栈中只有一个数字,该数字就是表达式的最终结果。
  9. 注意:2*3和2*13的区别,连续的数字字符的处理,通过拼接字符串来处理;
// 判断是否是运算符
public boolean isOper(int oper){
    return oper == '*' || oper == '/' || oper == '+' ||oper == '-';
}

// 定义运算符的优先级
public int priority(int oper){
    if (oper == '*' || oper == '/') {
        return 1;
    }else if (oper == '+' || oper == '-'){
        return 0;
    }else {
        return -1;
    }
}
// 定义运算规则
public int calculator(int oper,int num1,int num2){
    int res = 0; // 存放计算结果
    if (oper == '+') {
        res = num1+num2;
    }else if (oper == '-') {
        res = num2-num1; //注意这里是num2-num1,因为出栈先入后出
    }else if (oper == '*') {
        res = num1*num2;
    }else if (oper == '/') {
        res = num2/num1;
    }
    return res;
}

其他都是常规的入栈、出栈操作,此处就不分开列举了;

public class Calculator {
    public static void main(String[] args) {
        ArrayStack numStack = new ArrayStack(10);
        ArrayStack operStack = new ArrayStack(10);
        int num1 = 0;
        int num2 = 0;
        String moreNum = ""; //处理多位数
        int oper = 0;
        int result = 0;
        String data = "13+12*3-2";// String data = "3+2*12-2"; // 多位数出现问题
        char[] chars = data.toCharArray();
        for (int i=0; i<chars.length; i++) { // 这里不要用foreach,涉及到index操作
            // 判断是操作符,压入操作符栈
            if (operStack.isOper(chars[i])) {
                // 栈中没有操作符
                if (operStack.isEmpty()){
                    operStack.push(chars[i]); // 整数和单个字符是通用的
                }else if (operStack.priority(chars[i])<=operStack.priority(operStack.peek())){// 栈中有操作符,比较优先级,乘、除
                    num1 =  numStack.pop();
                    num2 = numStack.pop();
                    oper = operStack.pop();
                    result = numStack.calculator(oper,num1,num2);
                    // 将两个数的运算结果再次压入栈中
                    numStack.push(result);
                    // 当前运算符入栈
                    operStack.push(chars[i]);
                }else if (operStack.priority(chars[i])>operStack.priority(operStack.peek())){// 加、减
                    operStack.push(chars[i]);
                }
            }else {
                /*出现的问题:两位数以上,只有第一位被压入numStack,比如13,只压入1
                    // 判断是数字,压入运算符栈
                    numStack.push(ch-48); //ASCII码转换
                    // 比如0在ASCII中为48(数字从48开始),char-48得到真正的0
                */

                moreNum +=chars[i];
                // 判断当前位的下一位是否是数字(非运算符)
                if (i == chars.length-1){
                    numStack.push(Integer.parseInt(moreNum));
                }else{
                    if(operStack.isOper(chars[i+1])){
                        numStack.push(Integer.parseInt(moreNum));
                        moreNum = ""; // 防止出现多个多位数
                    }
                }
            }

        }
        // 此时栈中:numStack[2,6,3],operStack[-,+]
        while (true){
            if (operStack.isEmpty()){
                break;
            }
            num1 = numStack.pop();
            num2 = numStack.pop();
            oper = operStack.pop();
            result = numStack.calculator(oper,num1,num2);
            numStack.push(result);
        }
        // 栈中的最后一个元素就是运算结果
        result = numStack.pop();
        System.out.println(result);
    }
}

// 先创建一个栈
class ArrayStack{
    private int maxSize;
    private int[] stack;
    private int top = -1;

    public ArrayStack(int maxSize){
        this.maxSize = maxSize;
        stack = new int[this.maxSize];
    }

    public boolean isFull(){
        return top == maxSize-1;
    }
    public boolean isEmpty(){
        return top == -1;
    }

    // 1.入栈
    public void push(int value){
        if (isFull()){
            System.out.println("栈满,无法执行入栈操作");
            return;
        }
        top++;
        stack[top] = value;
    }

    // 2.出栈
    public int pop(){
        if (isEmpty()){
            throw new RuntimeException("栈空,无法执行出栈操作");
        }
        int data = stack[top];
        top--;
        return data;
    }

    // 3.显示栈中元素
    public void show(){
        if (isEmpty()){
            System.out.println("栈空,没有元素显示");
        }
        for (int i = top; i>=0 ; i--) {
            System.out.printf("Stack[%d]=%s\n",i,stack[i]); // 打印的是ASCII码值
        }
    }

    // 获取当前栈顶元素
    public int peek(){
        return stack[top];
    }

    // 判断是否是运算符
    public boolean isOper(int oper){
        return oper == '*' || oper == '/' || oper == '+' ||oper == '-';
    }

    // 定义运算符的优先级
    public int priority(int oper){
        if (oper == '*' || oper == '/') {
            return 1;
        }else if (oper == '+' || oper == '-'){
            return 0;
        }else {
            return -1;
        }
    }
    // 定义运算规则
    public int calculator(int oper,int num1,int num2){
        int res = 0; // 存放计算结果
        if (oper == '+') {
            res = num1+num2;
        }else if (oper == '-') {
            res = num2-num1; //注意这里是num2-num1,因为出栈先入后出
        }else if (oper == '*') {
            res = num1*num2;
        }else if (oper == '/') {
            res = num2/num1;
        }
        return res;
    }
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
房贷计算器是一个非常实用的工具,可以帮助人们计算出每月应还款和资产剩余情况。下面是一个简单的流程控制案例,用于实现房贷计算器的基本功能: 1. 首先,需要获取用户输入的个人总资产、月收入、目标房产相关信息和身上已有的车贷等信息。 2. 接下来,需要根据用户输入的信息计算出每月应还款和资产剩余情况。这个过程可以根据不同的贷款方式(等额本金和等额本息)进行计算。 3. 最后,将计算结果输出给用户,让用户了解每月应还款和资产剩余情况。 下面是一个简单的Python代码示例,用于实现房贷计算器的基本功能: ```python # 获取用户输入的个人总资产、月收入、目标房产相关信息和身上已有的车贷等信息 total_assets = float(input("请输入您的个人总资产:")) monthly_income = float(input("请输入您的月收入:")) house_price = float(input("请输入您的目标房产价格:")) down_payment = float(input("请输入您的首付款金额:")) loan_amount = house_price - down_payment car_loan = float(input("请输入您身上的车贷金额:")) # 计算每月应还款和资产剩余情况 interest_rate = 0.05 # 假设利率为5% month_num = 240 # 假设贷款期限为20年 monthly_payment = (loan_amount * interest_rate / 12 * (1 + interest_rate / 12) ** month_num) / ((1 + interest_rate / 12) ** month_num - 1) remaining_assets = total_assets - down_payment - car_loan # 输出计算结果 print("每月应还款:%.2f元" % monthly_payment) print("资产剩余:%.2f元" % remaining_assets) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值