在学习数据结构Java描述时,在堆栈部分遇到了中缀转后缀的题目。
1.后缀表达式的操作数与中缀表达式的操作数排列次序相同,只是运算符的排列次序改变;
2.后缀表达式中没有括号,后缀表达式的运算符次序就是其执行次序。
正是由于后缀表达式具有以上两个特点,编译系统在处理后缀表达式时不必考虑运
算符的优先关系。只要从左到右依次扫描后缀表达式的各个单词,当读到一个单词为运算符时,就对该运算符前边的两个操作数施以该运算符所代表的运算,然后将结果存入一个
临时单元T(i≥1)中,并作为一个新的操作数接着进行上述过程,直到表达式处理完毕为止。
综上所述,编译系统中表达式的计算分为以下两个步骤:
(1)把中缀表达式变换成相应的后缀表达式;
(2)根据后缀表达式计算表达式的值。
对于Java和数据结构的知识了解甚少,写出的代码粗糙不堪,变量命名随意混乱不够易读,缺少注释。类的定义混乱。由于将堆栈类定义为String类,所以在运行时涉及到反复的转型,代码不够简洁。这些都是我如今存在的极大的问题,我会在今后的学习中逐步更正。
下面放上这段修修补补的狗屎一样的代码,作为我学习的记录。
import java.io.*;
interface MySeqStack{
public void push(String obj) throws Exception;
public String pop() throws Exception;
public String getTop() throws Exception;
public boolean notEmpty() throws Exception;
public void setTop(String obj) throws Exception;
public String getElement(int index)throws Exception;
}
public class test {
public static void main(String[] srgs) throws Exception{
SeqStack atest=new SeqStack();
SeqStack x=new SeqStack();
String a="3+(6-4/2)*5#";
System.out.println("转换后的后缀表达式是:"+atest.reversePolandNotation(a));
atest.caculate(atest.reversePolandNotation(a));
}
}
class SeqStack implements MySeqStack {
final int defaultsize = 1000;
int top = 0;
String reversedPolandNotation;
String[] stack;
int maxStackSize = 100;
public int getTopNumber() {
return this.top;
}
SeqStack() {
initiate(defaultsize);
}
SeqStack(int size) {
initiate(size);
}
public void initiate(int size) {
stack = new String[size];
}
@Override
public void push(String obj) throws Exception {
if (this.top == maxStackSize) {
throw new Exception("堆栈已满");
}
stack[top] = obj;
this.top++;
}
@Override
public String pop() throws Exception {
if (this.top == maxStackSize) {
throw new Exception("堆栈已满");
}
this.top--;
return stack[top];
}
@Override
public String getTop() throws Exception {
if (this.top == 0) {
throw new Exception("堆栈已空");
}
return stack[this.top - 1];
}
@Override
public boolean notEmpty() throws Exception {
return (top > 0);
}
@Override
public void setTop(String obj) throws Exception {
stack[defaultsize - 1] = obj;
}
@Override
public String getElement(int index) throws Exception {
return stack[index];
}
public String reversePolandNotation(String aString) throws Exception {
SeqStack x = new SeqStack();
String afterReverse="";
x.push("#");
String x1;
String x2;
int sign = 0;
for (int i = 0; i < aString.length(); i++) {
x1 = x.getTop();
if (Character.isDigit(aString.charAt(i))) {
afterReverse+=aString.charAt(i);
continue;
}
x2 = String.valueOf(aString.charAt(i));
if ((int) (this.compare(String.valueOf(x1), String.valueOf(x2))) == 0) {
x.push(String.valueOf(x2));
} else if ((int) (this.compare(String.valueOf(x1), String.valueOf(x2))) == 1) {
afterReverse+=x.getTop();
x.pop();
i--;
} else if ((int) (this.compare(String.valueOf(x1), String.valueOf(x2))) == 2) {
if ((x1.equals("(")) && (x2.equals(")"))) {
x.pop();
} else {
afterReverse+=x.getTop();
x.pop();
}
} else break;
}
return afterReverse;
}
public int compare(String x, String y) throws Exception {
//flag数组存放x1与x2比较的结果,x1>x2为1,x1<x2为0,x1与x2为一对匹配的括号时为2,结束时为3,不存在值为-1
int[][] flag = {
{1, 1, 0, 0, 0, 1, 1},
{1, 1, 0, 0, 0, 1, 1},
{1, 1, 1, 1, 0, 1, 1},
{1, 1, 1, 1, 0, 1, 1},
{0, 0, 0, 0, 0, 2, -1},
{1, 1, 1, 1, -1, 1, 1},
{0, 0, 0, 0, 0, -1, 3}
};
int temp_x1 = 0;
int temp_x2 = 0;
if (x.equals("+")) temp_x1 = 0;
else if (x.equals("-")) temp_x1 = 1;
else if (x.equals("*")) temp_x1 = 2;
else if (x.equals("/")) temp_x1 = 3;
else if (x.equals("(")) temp_x1 = 4;
else if (x.equals(")")) temp_x1 = 5;
else if (x.equals("#")) temp_x1 = 6;
if (y.equals("+")) temp_x2 = 0;
else if (y.equals("-")) temp_x2 = 1;
else if (y.equals("*")) temp_x2 = 2;
else if (y.equals("/")) temp_x2 = 3;
else if (y.equals("(")) temp_x2 = 4;
else if (y.equals(")")) temp_x2 = 5;
else if (y.equals("#")) temp_x2 = 6;
return flag[temp_x1][temp_x2];
}
public void caculate(String aString)throws Exception{
SeqStack numberStack=new SeqStack();
char ch;
String operateOne;
String operateTwo;
int a;
int b;
for(int i=0;i<aString.length();i++){
ch=aString.charAt(i);
if(Character.isDigit(ch)){
numberStack.push(Character.toString(ch));
}else{
operateOne=numberStack.pop();
operateTwo=numberStack.pop();
a=Integer.valueOf(operateOne);
b=Integer.valueOf(operateTwo);
switch (ch){
case '+':
b+=a;
break;
case '-':
b-=a;
break;
case '*':
b*=a;
break;
case '/':
if(a==0){
throw new Exception("除数为0");
}else {
b/=a;
break;
}
}
numberStack.push(Integer.toString(b));
}
}
System.out.println("结果为:"+numberStack.pop());
}
}