转换思路:
1、中缀表达式转为字符数组按顺序遍历
2、读到操作数的时,添加到要输出字符串
3、读到操作符是“(”,则直接把“(”压入栈中。
4、读到操作符“)”,则从栈中弹出栈元素并添加到要输出的字符串,直到遇到第一个“(”为止
5、读到操作符“+”,“-”,若栈不为空且栈顶元素不是“(” 符号就弹栈中的数据,添加到要输出的字符串,否则就压栈
6、读到操作符“*”,“/”,若栈不为空且栈顶元素是“*”,“/”就从栈中弹出栈元素并输出添加到要输出字符串,否则就压栈
计算后缀表达式思路
1、后缀表达式转为字符数组按顺序遍历
2、若是数字就进行压栈操作,若是操作数就弹出两个进行运算
注意:用弹出的第二个数去操作(+ - * /)弹出的第一个数
代码实现
package com.zhl.dataStructure.stack;
import java.util.EmptyStackException;
import java.util.Stack;
/**
*
* @author Administrator
*
*/
public class Postfix {
/**
* 将后缀转换为后缀表达式
*
* @param infix
* @return
*/
public static String infixToPostfix(String infix) {
// 操作符栈-----'+ - * / ( )'
Stack<Character> op = new Stack<Character>();
StringBuilder postfixStr = new StringBuilder("");
char[] prefixs = infix.trim().toCharArray();
Character ch;
for (int i = 0; i < prefixs.length; i++) {
ch = prefixs[i];
// 如果是数字 0~9
if (ch >= '0' && ch <= '9') {
// vlaues.push(Integer.valueOf(ch));
postfixStr.append(ch);
continue;
}
// "("---直接压栈
if ('(' == ch) {
op.push(ch);
continue;
}
/*
* '+ - * /'----空栈直接压栈否则与栈顶元素比较, 优先级低于栈顶元素则弹出栈直到遇到优先级相等或者低的就停止弹栈
* 最后将该操作符压栈
*/
if ('+' == ch || '-' == ch) {
// 只要栈不为空,栈顶元素不是'(' 就弹栈
while (!op.empty() && (op.peek() != '(')) {
postfixStr.append(op.pop());
}
op.push(ch);
continue;
}
if ('*' == ch || '/' == ch) {
// 只要栈不为空,栈顶元素是'* /' 就弹栈
while (!op.empty() && (op.peek() == '*' || op.peek() == '/')) {
postfixStr.append(op.pop());
}
op.push(ch);
continue;
}
// ')'----开始弹栈直到遇到第一个'('
if (')' == ch) {
while (!op.empty() && op.peek() != '(') {
postfixStr.append(op.pop());
}
op.pop();// ----将'('元素弹出
continue;
}
}
// 所有字符遍历完毕操作数栈还有数据就全部弹栈
while (!op.empty())
postfixStr.append(op.pop());
return postfixStr.toString();
}
/**
* 计算后缀表达式
*
* @param postfix
* @return
*/
public static int sumPostfix(String postfix){
//操作数栈---暂时只考虑正整数
Stack<Integer> values;
int result=0;
try {
values = new Stack<Integer>();
char [] postfixs =postfix.trim().toCharArray();
Character ch;
for(int i=0;i<postfixs.length;i++){
ch=postfixs[i];
if(ch >= '0' && ch <= '9') {
values.push(Integer.valueOf(String.valueOf(ch)));//---如操作栈
//或者:*****这样更考验思维
//values.push(Integer.valueOf(ch-'0'));
}else {
result=operate(ch, values.pop(),values.pop());
values.push(result);
}
}
result=values.pop();
if(!values.empty()){
throw new Exception();
}
} catch (NumberFormatException e) {
System.out.println("数据转换出异常");
}catch(EmptyStackException e){//栈中为空还在进行弹栈操作
System.out.println("后缀表达式格式有问题");
}catch(Exception e){ // 符号都用完栈中还有多个数据
System.out.println("后缀表达式格式有问题");
}
return result;
}
public static int operate(char op,int value1,int value2){
int result=0;
//记住用第二个弹栈的值value2(加减乘除)第一个弹栈的值value1
switch ((int) op) {
case 43://'+'
result=value2+value1;
break;
case 45://'-'
result=value2-value1;
break;
case 42://'*'
result=value2*value1;
break;
case 47://'/'
result=value2/value1;
break;
default:
break;
}
return result;
}
public static void main(String[] args) {
String str="5+4*(3*(6-1*2+3))";
System.out.println(str+":"+infixToPostfix(str));
str=infixToPostfix(str);
System.out.println("result:"+sumPostfix(str));
}
}
测试结果: