zoukankan      html  css  js  c++  java
  • 栈:实现综合计算器(中缀表达式)

    使用栈实现综合计算器

    请输入一个表达式

    例:[3+2*6-2] ,直接点击计算,就可以计算出值。

    思路分析(图解)

     代码如下

    【1.先实现一位数的运算,2.扩展到多位数的运算】

      1 package com.jyj.stack;
      2 
      3 public class Calculator {
      4     public static void main(String[] args) {
      5         String expression = "30+2*6-2";
      6         //创建两个栈,数栈和符号栈
      7         ArrayStack2 numStack = new ArrayStack2(10);
      8         ArrayStack2 operStack = new ArrayStack2(10);
      9         //定义需要的相关变量
     10         int index = 0; //用于扫描
     11         int num1 = 0;
     12         int num2 = 0;
     13         int oper = 0;
     14         int res = 0;
     15         char ch = ' '; //将每次扫描得到char保存到ch
     16         String keepNum = "";//用于拼接 多位数
     17         //开始while循环的扫描expression
     18         while(true) {
     19             //依次得到expression的每一个字符
     20             ch = expression.substring(index, index+1).charAt(0);
     21             //判断ch是什么,然后做相应的处理
     22             if(operStack.isOper(ch)){//如果是运算符
     23                 //判断当前的符号栈是否为空
     24                 if(!operStack.isEmpty()) {
     25                     //如果符号栈有操作符,进行比较,如果当前操作符的优先级小于等于栈中的操作符,就需要从数栈中pop出两个数,
     26                     //在从符号栈中pop出一个符号,进行计算,将得到结果,入数栈,然后将当前的操作符入符号栈
     27                     if(operStack.priority(ch) <= operStack.priority(operStack.peek())) {
     28                         num1 = numStack.pop();
     29                         num2 = numStack.pop();
     30                         oper = operStack.pop();
     31                         res = numStack.cal(num1, num2, oper);
     32                         //把运算的结果入数栈
     33                         numStack.push(res);
     34                         //然后将当前的操作符入符号栈
     35                         operStack.push(ch);
     36                     } else {
     37                         //如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈。
     38                         operStack.push(ch);
     39                     }
     40                 }else {
     41                     //如果为空,就直接入符号栈
     42                     operStack.push(ch);
     43                 }
     44             }else{
     45                 //如果是数字,直接入数栈
     46                 //numStack.push(ch - 48);
     47                 //思路:
     48                 //1.当处理多位数时,不能发现是一个数,就立刻入栈,因为可能是多位数
     49                 //2.在处理数时,需要向expression的表达式的index后再看一位,如果是数,继续扫描,如果是符号,才入栈
     50                 //3.因此需要定义字符串keepNum,用于拼接 多位数
     51                 
     52                 //处理多位数
     53                 keepNum += ch;
     54                 
     55                 //如果ch已经是expression的最后一位,直接入栈
     56                 if(index == expression.length() - 1) {
     57                     numStack.push(Integer.parseInt(keepNum));
     58                 }else{
     59                     //判断下一个符号是不是数字,如果是数字,就继续扫描,如果是运算符,则入栈
     60                     //注意是看后一位,不是index++
     61                     if(operStack.isOper(expression.substring(index+1, index+2).charAt(0))){
     62                         numStack.push(Integer.parseInt(keepNum));
     63                         //注意:keepNum要清空
     64                         keepNum = "";
     65                     }
     66                 }
     67             }
     68             //让index + 1,并判断是否扫描到expression最后
     69             index++;
     70             if(index >= expression.length()) {
     71                 break;
     72             }
     73         }
     74         
     75         //当表达式扫描完毕,就顺序的从 数栈和符号栈中pop出相应的数和符号,并运行。
     76         while(true) {
     77             //如果符号栈为空,则计算到最后的结果,数栈中只有一个数字[结果]
     78             if(operStack.isEmpty()) {
     79                 break;
     80             }
     81             num1 = numStack.pop();
     82             num2 = numStack.pop();
     83             oper = operStack.pop();
     84             res = numStack.cal(num1, num2, oper);
     85             numStack.push(res);
     86         }
     87         System.out.printf("表达式 %s = %d
    ",expression,numStack.pop());
     88     }
     89 }
     90 
     91 //定义ArrayStack2表示栈,需要扩展
     92 class ArrayStack2 {
     93     private int maxSize; //栈的大小
     94     private int top = -1; //栈顶,初始化为-1
     95     private int[] stack;
     96     
     97     public ArrayStack2(int size) {
     98         maxSize = size;
     99         stack = new int[maxSize];
    100     }
    101     
    102     //增加一个方法,可以返回当前栈顶的值,但是不是真的的pop
    103     public int peek() {
    104         return stack[top];
    105     }
    106     
    107     //栈满
    108     public boolean isFull(){
    109         return top == maxSize - 1;
    110     }
    111     //栈空
    112     public boolean isEmpty(){
    113         return top == -1;
    114     }
    115     //入栈-push
    116     public void push(int value) {
    117         if(isFull()){
    118             System.out.println("栈满");
    119             return;
    120         }
    121         top++;
    122         stack[top] = value;
    123     }
    124     
    125     //出栈-pop
    126     public int pop(){
    127         if(isEmpty()){
    128             throw new RuntimeException("栈空");
    129         }
    130         int value = stack[top];
    131         top--;
    132         return value;
    133     }
    134     
    135     //显示栈[遍历数据]
    136     public void list(){
    137         //判空
    138         if(isEmpty()){
    139             System.out.println("栈空,没有数据");
    140         }
    141         //遍历
    142         for(int i = top;i >= 0;i--) {
    143             System.out.printf("stack[%d] = %d
    ",i,stack[i]);
    144         }
    145     }
    146     //返回运算符的优先级,优先级是程序员来确定,优先级使用数字来表示
    147     //数字越大,则优先级就越高
    148     public int priority(int oper) {
    149         if(oper == '*' || oper == '/') {
    150             return 1;
    151         }else if(oper == '+' || oper == '-') {
    152             return 0;
    153         }else {
    154             return -1;//假定目前的表达式只有+,-,*,/
    155         }
    156     }
    157     //判断是不是一个运算符
    158     public boolean isOper(char val) {
    159         return val == '+' || val == '-' || val == '*' || val == '/';
    160     }
    161     
    162     //计算
    163     public int cal(int num1,int num2,int oper) {
    164         int res = 0;
    165         switch(oper) {
    166         case '+':
    167             res = num1 + num2;
    168             break;
    169         case '-':
    170             res = num2 - num1; //注意顺序
    171             break;
    172         case '*':
    173             res = num1 * num2;
    174             break;
    175         case '/':
    176             res = num2 / num1;
    177             break;
    178         }
    179         return res;
    180     }
    181 }
    View Code

    以上。

    朱子家训说:宜未雨而筹谋,勿临渴而掘井。 任何事情要到了跟前才想解决办法,那我们岂不很被动!
  • 相关阅读:
    Google V8编程详解(四)Context
    Google V8编程详解附录
    Google V8编程详解(三)Handle & HandleScope
    Google V8编程详解(二)HelloWorld
    Google V8编程详解(一)V8的编译安装(Ubuntu)
    Google V8编程详解(序)Cloud App
    makefile:2: *** 遗漏分隔符 。 停止
    HTTP协议各个参数详解
    java&android知识点汇总整理(不定期更新)
    错误一览表
  • 原文地址:https://www.cnblogs.com/jianyingjie/p/12369384.html
Copyright © 2011-2022 走看看