数据结构(3)-JAVA-顺序栈实现表达式求值

结构框架:

在这里插入图片描述
Expression: 把中缀表达式转换成后缀形式,计算后缀表达式的结果
IStack:栈的抽象数据类型
SqStack:栈的顺序存储结构:顺序栈
Test:测试类

IStack:

package ds.expression;
/***
 * 栈的抽象数据类型
 * @author 1
 *
 */
public interface IStack {
 //置空栈clear
 public void clear();
 //判空栈isEmpty
 public boolean isEmpty();
 //进栈push
 public void push(Object x)throws Exception;
 //退栈pop
 public Object pop();
 //取栈顶top
 public Object top();
 //输出元素
 public void display();
}

SqStack:

package ds.expression;
/***
 * 栈的顺序存储结构:顺序栈
 * 
 * @author 1
 * 
 */
 public class SqStack implements IStack {
 // 连续空间data
 private Object[] data;
 // 栈顶指针top
 private int top;
// 构造方法
 public SqStack(int n) {
  data = new Object[n];
  this.top = 0;
 }
 // 无参构造方法
 public SqStack() {
 }
 
 // 实现接口中的方法
 // 置空栈clear
 @Override
 public void clear() {
  // TODO Auto-generated method stub
  top = 0;
 }
 
 // 判空栈isEmpty
 @Override
 public boolean isEmpty() {
  // TODO Auto-generated method stub
  if(top==0){
   return true;
  }else{
   return false;
  }
  // 栈满 top==n进栈出现上溢overflow // 出栈操作则是下溢underflow
 }
 
 // 进栈push
 @Override
 public void push(Object x) throws Exception {
  // TODO Auto-generated method stub
  if (top == data.length) {// 栈满
   throw new Exception("overflow");// 栈已满抛出异常
  } else {
   data[top]=x;
   top++;
  }
 }
 
 // 退栈pop
 @Override
 public Object pop() {// 判断是否出现下溢
   //TODO Auto-generated method stub
  if (isEmpty()) {
   System.out.println("underflow");
   return null;
  } else {
   top --;
   return data[top];
  }
 }
 
 // 取栈顶top
 @Override
 public Object top() {
  // TODO Auto-generated method stub
  if (!isEmpty()) {
   return data[top - 1];
  } else {
   return null;
  }
 }
 
 @Override
 public void display() {
  // TODO Auto-generated method stub
  for (int i = top - 1; i >= 0; i--) {
   System.out.println(data[i].toString() + "");// 输出
  }
 }
}

Expression:

package ds.expression;
/***
 * 把中缀表达式转换成后缀形式,计算后缀表达式的结果
 * 
 * @author 1
 * 
 */
 public class Expression {
 // 把中缀表达式转换成后缀形式convertToPost (2+3)-5*6/3==>23+56*3/-
 public String convertToPost(String exp) throws Exception {
  SqStack st = new SqStack(30);// 创建顺序栈对象
  StringBuffer post = new StringBuffer();// 创建StringBuffer对象
  for (int i = 0; i < exp.length(); i++) {// 依次判断exp中的每个字符
   char ch = exp.charAt(i);
   if (ch != ' ') {
    if (isLeft(ch)) {// 如果ch是左括号
     st.push(ch);// 字符ch进栈
    } else if (isRight(ch)) {// 如果ch是右括号
    // 退栈,把退栈的字符追加到post末尾直到退栈的字符为左括号为止
     char x = (Character) st.pop();
     while (!isLeft(x)) {
      post.append(x);
      x = (Character) st.pop();
     }
    } else if (isOperator(ch)) {// 如果ch是操作符
    if (!st.isEmpty()) {// 如果栈非空
      Character x = (Character) st.top();
      while (x != null && priority(ch) <= priority(x)) {// 把ch与栈顶符号的优先级进行比较,如果ch的优先级低于栈顶符号优先级
       post.append(st.pop());
       x = (Character) st.top();// 把栈顶符号退栈,追加post末尾
      }
     }
     st.push(ch);// 字符ch进栈
    } else {// 如果ch是操作数
     post.append(ch);// 直接把ch追加到post末尾
    }
   }
  }
  
  // 如果栈非空,把栈中剩余字符依次追加到post末尾
  while (!st.isEmpty()) {
   post.append(st.pop());// 栈中剩余的所有操作符 串联到后缀表达式的结尾
  }
  return post.toString();
 }
 
 // 判断符号是否为左括号isLeft
 public boolean isLeft(char ch) {
  return ch == '(';
 }
 
 // 判断符号是否为右括号isRight
 public boolean isRight(char ch) {
  return ch == ')';
 }
 
 // 判断符号是否为操作符isOperator
 public boolean isOperator(char ch) {
  if (ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='^'||ch=='%') {
   return true;
  } else {
   return false;
  }
 }
 
 // 设置符号优先级 () +- */ % ^ priority
 public int priority(char ch) {
  if (ch == '+' || ch == '-') {
   return 1;
  } else if (ch == '*' || ch == '/' || ch == '%') {
   return 2;
  } else if (ch == '^') {
   return 3;
  } else {
   return 0;
  }
 }
 
 // 计算后缀表达式的值calculate 0 1 2 3 4 5
 // -5
 public double calculate(String post) throws Exception {
 // 创建顺序栈对象
  SqStack st = new SqStack(30);
  // 依次提取post中的每个字符ch
  for (int i = 0; i < post.length(); i++) {
   char ch = post.charAt(i);
   // 如果字符ch为操作符
   if (isOperator(ch)) {
   // 退栈得到x
    double x = Double.parseDouble(st.pop().toString());
    // 退栈得到y
    double y = Double.parseDouble(st.pop().toString());
    // 进行ch运算,r=ychx
    double r = 0;
    if ('+' == ch) {
     r = y + x;
    } else if ('-' == ch) {
     r = y - x;
    } else if ('*' == ch) {
     r = y * x;
    } else if ('/' == ch) {
     r = y / x;
    } else if ('%' == ch) {
     r = y % x;
    } else if ('^' == ch) {
     r = Math.pow(y, x); // 幂运算
    }
    st.push(r);// 把结果r进栈
    } else {
    // 否则 操作数
    st.push(ch);// 进栈
   }
  }
  return (Double) st.top();//返回栈顶数据
 }
}

Test:

public static void main(String[] args) throws Exception {
  Expression resExp = new Expression();
  String exp="(2+3)-5*6/3";// 输入中缀表达式
  String post = resExp.convertToPost(exp);
  System.out.println(exp+"转化为后缀表达式为:"+post);// 把中缀表达式转换为后缀形式,并输出
  System.out.println("计算的结果为:" + resExp.calculate(post)); // 计算后缀表达式的值
 }

运行效果截图:

在这里插入图片描述
测试功能一切正常,基本运算没有完全加到测试类里面,该文章仅供自己复习和提供一些思路给大家,如果有发现的错误,麻烦大家及时指出。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你白勺男孩TT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值