评论

收藏

[Java] java中应用Stack进行算术运算的操作

编程语言 编程语言 发布于:2021-09-11 20:43 | 阅读数:430 | 评论:0

这篇文章主要介绍了java中应用Stack进行算术运算的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
java.util.stack,继承自Vector
FILO, 适合带有小括号的算术运算
import java.util.Stack; 
/**  
 * 利用栈,进行四则运算的类  
 * 用两个栈来实现算符优先,一个栈用来保存需要计算的数据numStack,一个用来保存计算优先符priStack  
 *  
 * 基本算法实现思路为:用当前取得的运算符与priStack栈顶运算符比较优先级:若高于,则因为会先运算,放入栈顶;  
 * 若等于,因为出现在后面,所以会后计算,所以栈顶元素出栈,取出操作数运算;  
 * 若小于,则同理,取出栈顶元素运算,将结果入操作数栈。各个优先级'(' > '*' = '/' > '+' = '-' > ')'  
 *  
 */  
public class Operate {   
  private Stack<Character> priStack = new Stack<Character>();// 操作符栈   
  private Stack<Integer> numStack = new Stack<Integer>();;// 操作数栈   
   
  /**  
   * 传入需要解析的字符串,返回计算结果(此处因为时间问题,省略合法性验证)  
   * @param str 需要进行技术的表达式  
   * @return 计算结果  
   */  
  public int caculate(String str) {   
  // 1.判断string当中有没有非法字符   
  String temp;// 用来临时存放读取的字符   
  // 2.循环开始解析字符串,当字符串解析完,且符号栈为空时,则计算完成   
  StringBuffer tempNum = new StringBuffer();// 用来临时存放数字字符串(当为多位数时)   
  StringBuffer string = new StringBuffer().append(str);// 用来保存,提高效率   
   
  while (string.length() != 0) {   
    temp = string.substring(0, 1);   
    string.delete(0, 1);   
    // 判断temp,当temp为操作符时   
    if (!isNum(temp)) {   
    // 1.此时的tempNum内即为需要操作的数,取出数,压栈,并且清空tempNum   
    if (!"".equals(tempNum.toString())) {   
      // 当表达式的第一个符号为括号   
      int num = Integer.parseInt(tempNum.toString());   
      numStack.push(num); 
      tempNum.delete(0, tempNum.length());   
    }   
    // 用当前取得的运算符与栈顶运算符比较优先级:若高于,则因为会先运算,放入栈顶;若等于,因为出现在后面,所以会后计算,所以栈顶元素出栈,取出操作数运算;   
    // 若小于,则同理,取出栈顶元素运算,将结果入操作数栈。   
   
    // 判断当前运算符与栈顶元素优先级,取出元素,进行计算(因为优先级可能小于栈顶元素,还小于第二个元素等等,需要用循环判断)   
    while (!compare(temp.charAt(0)) && (!priStack.empty())) {  
      int a = (int) numStack.pop();// 第二个运算数   
      int b = (int) numStack.pop();// 第一个运算数   
      char ope = priStack.pop();   
      int result = 0;// 运算结果   
      switch (ope) {   
      // 如果是加号或者减号,则   
      case '+':   
      result = b + a;   
      // 将操作结果放入操作数栈   
      numStack.push(result);   
      break;   
      case '-':   
      result = b - a;   
      // 将操作结果放入操作数栈   
      numStack.push(result);   
      break;   
      case '*':   
      result = b * a;   
      // 将操作结果放入操作数栈   
      numStack.push(result);   
      break;   
      case '/':   
      result = b / a;// 将操作结果放入操作数栈   
      numStack.push(result);   
      break;   
      }   
   
    }   
    // 判断当前运算符与栈顶元素优先级, 如果高,或者低于平,计算完后,将当前操作符号,放入操作符栈   
    if (temp.charAt(0) != '#') {   
      priStack.push(new Character(temp.charAt(0)));   
      if (temp.charAt(0) == ')') {// 当栈顶为'(',而当前元素为')'时,则是括号内以算完,去掉括号   
      priStack.pop();   
      priStack.pop();   
      }   
    }   
    } else  
    // 当为非操作符时(数字)   
    tempNum = tempNum.append(temp);// 将读到的这一位数接到以读出的数后(当不是个位数的时候)   
  }   
  return numStack.pop();   
  }   
   
  /**  
   * 判断传入的字符是不是0-9的数字  
   *  
   * @param str  
   *    传入的字符串  
   * @return  
   */  
  private boolean isNum(String temp) {   
  return temp.matches("[0-9]");   
  }   
   
  /**  
   * 比较当前操作符与栈顶元素操作符优先级,如果比栈顶元素优先级高,则返回true,否则返回false  
   *  
   * @param str 需要进行比较的字符  
   * @return 比较结果 true代表比栈顶元素优先级高,false代表比栈顶元素优先级低  
   */  
  private boolean compare(char str) {   
  if (priStack.empty()) {   
    // 当为空时,显然 当前优先级最低,返回高   
    return true;   
  }   
  char last = (char) priStack.lastElement();   
  // 如果栈顶为'('显然,优先级最低,')'不可能为栈顶。   
  if (last == '(') {   
    return true;   
  }   
  switch (str) {   
  case '#':   
    return false;// 结束符   
  case '(':   
    // '('优先级最高,显然返回true   
    return true;   
  case ')':   
    // ')'优先级最低,   
    return false;   
  case '*': {   
    // '*/'优先级只比'+-'高   
    if (last == '+' || last == '-')   
    return true;   
    else  
    return false;   
  }   
  case '/': {   
    if (last == '+' || last == '-')   
    return true;   
    else  
    return false;   
  }   
    // '+-'为最低,一直返回false   
  case '+':   
    return false;   
  case '-':   
    return false;   
  }   
  return true;   
  }   
   
  public static void main(String args[]) {   
  Operate operate = new Operate();   
  int t = operate.caculate("(3+4*(4*10-10/2)#");  
  System.out.println(t);   
  }   
   
}
补充:java stack实现的中缀简单四则运算表达式计算
我就废话不多说了,大家还是直接看代码吧~
public abstract class Stack<T> {
  public abstract boolean isEmpty();
  public abstract boolean isFull();
  public abstract T top();
  public abstract boolean push(T x);
  public abstract T pop();
  public abstract void clear();
}
public class SeqStack<T> extends Stack<T> {
  private Object[] elementData;
  private int maxTop;
  private int top;
  public SeqStack(int size) {
  this.maxTop = size - 1;
  elementData = new Object[size];
  top = -1;
  }
  @Override
  public boolean isEmpty() {
  return top == -1;
  }
  @Override
  public boolean isFull() {
  return top == maxTop - 1;
  }
  @SuppressWarnings("unchecked")
  @Override
  public T top() {
  if (top == -1) {
    System.out.println("Empty");
    return null;
  }
  return (T) elementData[top];
  }
  @Override
  public boolean push(T x) {
  if (top == maxTop) {
    System.err.println("Full");
    return false;
  }
  elementData[++top] = x;
  return true;
  }
  @SuppressWarnings("unchecked")
  @Override
  public T pop() {
  if (top == -1) {
    System.err.println("Empty");
    return null;
  }
  
  T result = (T)elementData[top];
  elementData[top] = null; //gc
  top--;
  return result;
  }
  @Override
  public void clear() {
  
  //let gc do its work
  for(int i = 0; i < top+1; i++) {
    
    elementData[i] = null;
  }
  
  top = -1;
  }
}
public class StackCalc {
  private SeqStack<Integer> stack;
  public StackCalc(int maxSize) {
  stack = new SeqStack<Integer>(maxSize);
  }
  private void pushOperand(Integer number) {
  stack.push(number);
  }
  private Number doOperate(char oper) {
  Integer right = stack.pop();
  Integer left = stack.pop();
  Integer result = null;
  if (left != null && right != null) {
    switch (oper) {
    case '+':
    result = left.intValue() + right.intValue();
    break;
    case '-':
    result = left.intValue() - right.intValue();
    break;
    case '*':
    result = left.intValue() * right.intValue();
    break;
    case '/':
    if (right.intValue() == 0) {
      System.err.println("Divide by 0");
    }
    result = left.intValue() / right.intValue();
    break;
    default:
    break;
    }
  }
  stack.push(result);
  return result;
  }
  private int icp(char c) {
  switch (c) {
  case '#':
    return 0;
  case '(':
    return 7;
  case '*':
    return 4;
  case '/':
    return 4;
  case '+':
    return 2;
  case '-':
    return 2;
  case ')':
    return 1;
  default:
    return -1;
  }
  }
  private int isp(int c) {
  switch (c) {
  case '#':
    return 0;
  case '(':
    return 1;
  case '*':
    return 5;
  case '/':
    return 5;
  case '+':
    return 3;
  case '-':
    return 3;
  case ')':
    return 7;
  default:
    return -1;
  }
  }
  public String transfer(String expression) {
  StringBuilder sb = new StringBuilder();
  SeqStack<Character> stack = new SeqStack<Character>(expression.length());
  stack.push('#');
  for (int i = 0; i < expression.length(); i++) {
    Character c = expression.charAt(i);
    if ('0' <= c && c <= '9' || 'a' <= c && c <= 'z' ||
      'A' <= c && c <= 'Z') { // digit character
    sb.append(c);
    } else { // 操作符
    if (icp(c) > isp(stack.top())) { // 进栈
      stack.push(c);
    } else { // 出栈
      if (c == ')') {
      char ch = stack.pop();
      while (ch != '(') {
        sb.append(ch);
        ch = stack.pop();
      }
      } else {
      char ch = stack.pop();
      while (icp(c) <= isp(ch)) {
        sb.append(ch);
        ch = stack.pop();
      }
      stack.push(ch);
      stack.push(c);
      }
    }
    }
  } // end of for
  char ch = stack.pop();
  while (ch != '#') {
    
    sb.append(ch);
    ch = stack.pop();
  }
  stack.clear();  
  return sb.toString();
  }
  public Integer calc(String expression) {
  expression = transfer(expression);
  for (int i = 0; i < expression.length(); i++) {
    char c = expression.charAt(i);
    switch (c) {
    case '+':
    case '-':
    case '*':
    case '/':
    doOperate(c);
    break;
    default:
    pushOperand(new Integer(c + ""));
    break;
    }
  }
  return stack.pop();
  }
  /**
   * @param args
   */
  public static void main(String[] args) {
  StackCalc calc = new StackCalc(10);
  System.out.println(calc.calc("6/(4-2)+3*2"));
  }
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持CodeAE代码之家。如有错误或未考虑完全的地方,望不吝赐教。
原文链接:https://blog.csdn.net/kangbin825/article/details/71437086

关注下面的标签,发现更多相似文章