栈实现综合计算器

思路分析:

 

 代码实现:

package stack;

public class Calculator {
public static void main(String[] args) {
    String expression="7+2*60-4";//如何处理多位数的问题?
    //创建两个栈,一个数栈,一个符号栈
    ArrayStack2 numStack= new ArrayStack2(10);
    ArrayStack2 operStack = new ArrayStack2(10);
    //定义相关变量
    int index=0;//用于扫描
    int num1=0;
    int num2=0;
    int oper=0;
    int res=0;
    char ch=' ';//将每次扫描得到char保存到ch
    String keepNum="";
    //开始while循环扫描expression
    while(true) {
        //以此得到expression的每一个字符
        ch=expression.substring(index,index+1).charAt(0);
        //判断ch
        if(operStack.isOper(ch)) {
            //判断当前符号栈是否为空
            if(!operStack.isEmpty()) {
                //如果符号栈有操作符,就进行比较,如果当前的操作符优先级小于或者等于栈中的操作
                if(operStack.priority(ch)<=operStack.priority(operStack.peek())){
                num1=numStack.pop();
                num2=numStack.pop();
                oper=operStack.pop();
                res=numStack.cal(num1, num2, oper);
                //把运算结果入数栈
                numStack.push(res);
                //把当前的操作符入符号栈
                operStack.push(ch);
                }else {
                    //直接入栈
                    operStack.push(ch);
                }
            }else {
                //如果为空,直接入符号栈
                operStack.push(ch);
                }
    }else {
        //如果是数栈,则直接入数栈
        //当处理多位数时。不能发现是一个数就立即入栈
        //在处理时,需要向expression的表达式的index后再看一位,如果是数,就进行扫描,如果是·符号才入栈
        //因此我们需要定义一个变量字符串,用于拼接
        keepNum+=ch;
        //如果ch已经是expression最后一位
        if(index==expression.length()-1) {
            numStack.push(Integer.parseInt(keepNum));
        }else {
        //判断下一个字符是不是数字
        if(operStack.isOper(expression.substring(index+1,index+2).charAt(0))) {
            //如果后一位是运算符,则入栈
            numStack.push(Integer.parseInt(keepNum));
            keepNum="";
        }
//        numStack.push(ch-48);
        }
        }
        //让index+1,并判断是否扫描到expression最后
        index++;
        if(index>=expression.length()) {
            break;
        }
    }
    while(true) {
        //如果符号栈为空,则计算到最后的结果
        if(operStack.isEmpty()) {
            break;
        }num1=numStack.pop();
        num2=numStack.pop();
        oper=operStack.pop();
        res=numStack.cal(num1, num2, oper);
        numStack.push(res);
    }
    System.out.printf("表达式%s=%d",expression,numStack.pop());
}
}
//先创建一个栈,需要扩展功能
class ArrayStack2{
    private int maxSize;
    private int[] stack;//数组模拟栈,数据就放在该数组
    private int top=-1;
    //构造器
    public ArrayStack2(int maxSize) {
        this.maxSize=maxSize;
        stack=new int[this.maxSize];
    }
    //增加一个方法,可以返回当前栈顶的值但是不pop
    public int peek() {
        return stack[top];
    }
    //栈满
    public boolean isFull() {
        return top==maxSize-1;
    }
    //栈空
    public boolean isEmpty() {
        return top==-1;
    }
    //入栈
    public void push (int value) {
        //先判断栈是否满
        if(isFull()) {
            System.out.println("栈满");
            return;
        }
        top++;
        stack[top]=value;
    }
    //出栈
    public int pop() {
        if(isEmpty()) {
            //抛异常处理
            throw new RuntimeException( "栈空,没有数据");
        }
        int value=stack[top];
        top--;
        return value;
    }
    //遍历栈,需要从栈顶开始显示数据
    public void list() {
        if(isEmpty()) {
            System.out.println("栈空,没有数据");
            return;
        }
        for(int i=top;i>=0;i--) {
            System.out.printf("stack[%d]=%d\n",i,stack[i]);
        }
    }
    //返回运算符的优先级,优先级是程序员来确定的,优先级使用数字表示,数字越大,优先级越高
    public int priority(int oper) {
        if(oper=='*'||oper=='/') {
            return 1;
        }else if(oper=='+'||oper=='-') {
            return 0;
        }else {
            return -1;//假定目前表达式只有加减乘除
        }
        }
    //判断是不是运算符
    public boolean isOper(char val) {
        return val=='+'||val=='-'||val=='*'||val=='/';
    }
    //计算方法
    public int cal(int num1,int num2,int oper) {
        int res=0;//用于存放计算结果
        switch (oper) {
        case '+':
            res=num1+num2;
            break;
        case '-':
            res=num2-num1;//注意顺序
            break;
        case '*':
            res=num1*num2;
            break;
        case '/':
            res=num2/num1;
            break;

        default:
            break;
        }
        return res;
    }
}

 

posted @ 2019-10-16 20:27  Boogiever  阅读(846)  评论(0编辑  收藏  举报