结构框架:
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)); // 计算后缀表达式的值
}
运行效果截图:
测试功能一切正常,基本运算没有完全加到测试类里面,该文章仅供自己复习和提供一些思路给大家,如果有发现的错误,麻烦大家及时指出。