目录
class StackCalculator的PostFix方法
表达式的转换:
表达式一般有中级表达式、后缀表达式和前缀表达式3种表示形式,通常我们使用中缀表示,但是中缀表达式在计算机中存储计算时,比较麻烦,所以计算机内存储表达式时,一般采用后缀或前缀表示较多。
一个表达式通常由操作数、运算符及分隔符所构成。一般我们习惯使用中缀描述法,也就是将运算符放在操作数中间,例如:a+b*c
由于运算符有优先级,所以在计算机内部使用中缀描述是非常不方便的,特别是带有括号时更麻烦。为方便处理起见,一般需要将中级的表达式利用堆栈转换成为计算机比较容易识别(没有括号)的前缀或后缀表达式,这样在扫描表达式时,只要按照运算符直接计算即可。例如:
+a*bc 前缀表达式
abc*+ 后缀表达式
中缀表达式 9+(3-1)×3+10÷2
后缀表达式 9 3 1-3*+10 2/+
中缀表达式转后缀表达式 转换原则:
* 1 从左至右读取一个表达式。
* 2 若读取的是操作数,则直接输出。
* 3 若读取的是运算符,分3种情况:
* (1)左括号“(”直接存入堆栈;
* (2)右括号“)”输出堆栈中的运算符,直到取出左括号为止;
* (3)非括号运算符,优先级比栈顶高的直接存入堆栈,比栈顶低或相等则输出堆栈中的运算符。
* 4 表达式读取完成后,依次取出堆栈中的运算符,直到堆栈为空。
运算符优先级:
假设栈顶元素的运算符是θ1,新读到的元素是θ2
代码:
public class StackCalculator {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String inorder = in.nextLine(); //读取表达式并转换,直到退出
while (!inorder.equals("exits")) {
String newOrder = PostFix(inorder); //转换表达式
System.out.println(newOrder);
inorder = in.nextLine();
}
}
输入:9+(3-1)*3+10/2输出:931-3*+102/+
class StackCalculator的PostFix方法
public static String PostFix(String infix){
StringBuilder postfix = new StringBuilder();
int position = 0;
ArrayStack operator = new ArrayStack(); //运算符堆栈
//从左至右中缀表达式遍历字符串
while (position < infix.length()){
char cur = infix.charAt(position++); //保存当前字符
//1.数字直接输出
if (!operator.isOperator(cur)) {
postfix.append(cur);
continue;
}
//2.左括号直接入栈
if (operator.top == -1 || cur=='(') {
operator.push(cur);
}
/*3.若是右括号,取出运算符直到取出'(',若无'('配对则抛出异常
若是运算符‘+’或‘-’(优先级只比'('高):
1.栈内有'(',则取出'('上面的运算符,将当前运算符添加到栈顶;
2.否则全部出栈,并将当前运算符添加到栈顶。
*/
else if (cur == ')' || operator.priority(cur) <= operator.priority(operator.topElement())){
boolean takeOut = false;
while(operator.top != -1) {
if (operator.topElement() == '(') {
operator.pop2();
takeOut = true;
break;
}
postfix.append(operator.pop2());
}
if (operator.top == -1)
if (cur == ')' && !takeOut)
throw new RuntimeException("Error:No '(' in th left of ')'");
else operator.push(cur);
}
//运算符* /入栈
else
operator.push(cur);
}
//字符串遍历完后,将堆栈中的运算符全部弹出
while (operator.top!=-1)
postfix.append(operator.pop2());
return postfix.toString();
}
}
ArrayStack类模拟堆栈:先进后出
class ArrayStack{
char[] stack ;
public int top;
private final int capacity = 10;
ArrayStack(){
this.top = -1;
this.stack = new char[capacity];
}
public boolean push(char element){
if (top == capacity-1) {
System.out.println("Stack overFlow");
return false;
}
stack[++top] = element;
return true;
}
public char pop2(){
char topElement;
char[] l = this.stack;
if (top == -1){
System.out.println("Empty Stack");
return '\u0000';
}
topElement = l[top];
l[top--] = '\u0000';
return topElement;
}
public char topElement() throws RuntimeException {
if (top == -1) {
return '\u0000';
}
else
return this.stack[top];
}
public boolean isOperator(char operator){
return operator == '+' || operator == '-' ||
operator == '*' || operator == '/' ||
operator == '(' || operator == ')';
}
public int priority(char operator) {
switch (operator) {
case '+':
case '-':
return 1;
case '*':
case '/':
//case '(':
return 2;
}
return 0;
}
}