此示例值只使用了+ - * / 和小括号,但基本思路已经很清晰了!!!
解析成后缀表达式,用之前的逆波兰java的博客里面的java代码算出结果!
/*
* 例如:1*(2+3+(5-4))+6
*
* 开始括号:( [ {
* 结束括号:} ] )
*
* 基本思路:
* 1. 在解析的时候,因为如果解析到6的话,已经到结尾了,但程序不知道是否,应该取出栈中存放的运算符号。
* 也可以在遍历结束之后,在取出栈中的运算符,但我选择的是在原字符串基础上加一个结束标志,我使用的是!(叹号)
* 2. 如果是数字就加入到代表后缀表达式代表的字符串中
* 3. 如果是运算符(+ - * /)就都压入栈中
* 4. 如果是大中小开始括号,也同样压入栈中
* 5. 在栈中没有括号的情况下:
* 碰到 加号(+)或者减号( -),就取出栈中所有的运算符,在将+或—压入栈中
* 6. 在栈中有括号的情况下:
* 碰到 加号(+)或者减号( -),取出栈中的运算符,直到碰到开始括号为止(开始括号不取出来!!!),
* 在将当前+或者-压入栈中。
* 7. 在栈中有括号的情况下:
* 碰到结束括号,取出栈中的运算符,直到取出与之配置开始括号为止(开始括号也取出来!!!)。
* 8. 碰到结束标志(!)如果栈中不为空全部取出,结束遍历算数表达式。
*
*
* 示例解析:1*(2+3+(5-4))+6!
* 算数表达式 栈(解析完算数表达式后) 后缀表达式
* 1 1
* 1* * 1
* 1*( *( 1
* 1*(2 *( 12
* 1*(2+(应该执行第5步) *(+ 12
* 1*(2+3 *(+ 123
* 1*(2+3+ *(+ 123+
* 1*(2+3+( *(+( 123+
* 1*(2+3+(5 *(+( 123+5
* 1*(2+3+(5- *(+(- 123+5
* 1*(2+3+(5-4 *(+(- 123+54
* 1*(2+3+(5-4)(应该执行第6步)*(+ 123+54-
* 1*(2+3+(5-4)) * 123+54-+
* 1*(2+3+(5-4))+ + 123+54-+*
* 1*(2+3+(5-4))+6 + 123+54-+*6
* 1*(2+3+(5-4))+6! 123+54-+*6+
*
*/
@Test
public void test() {
String str = "2+(1+(2*4/(2/1))*6+(1-2))*4+5";
//应先判断算数表达式中的括号是否匹配
String expression = this.createSuffixExp(str);
System.out.println(expression); // 212421//*6*+12-+4*+5+
}
public String createSuffixExp(String str) {
int num = 0; //记录栈中的开始括号个数
int stackLen = 0;
String template = "";
Stack<Character> stack = new Stack<Character>(30);
str = str + "!"; //第1步,要在这里加,不要在for循环的执行条件里面加!会有字符串的相关问题!
for(int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if(c == '(') {
++num;
stack.push(c); //第4步
} else if (c == '-' || c == '+' || c == '!') { //判断是否是 + - !
if(num > 0) { //判断是否有开始括号
stackLen = stack.getLen();
for(int j = 0; j < stackLen; j++ ) { //第6步
char element = stack.peak();
if(element == '(') {
break;
}
template += stack.pop();
}
} else { //第5步,栈中没有括号
if(stack.getLen() != 0) {
/*
* int stackLen = stack.getLen();应当先获得stack的大小
* 因为每当stack移除一项之后,for循环判断stack.getLen都会减1
* 也就是j在不断增减,这样就会出现问题!!!
*/
stackLen = stack.getLen();
for(int j = 0; j < stackLen; j++ ) {
template += stack.pop();
}
}
}
if(c == '!') { //第8步
break ;
}
stack.push(c); //第3步
} else if (c == '*' || c == '/') { //判断是否是 * /
stack.push(c); //第3步
} else if (c == ')') {
stackLen = stack.getLen();
for(int k = 0; k < stackLen; k++) { //第7步
char element = stack.pop();
if(element == '(') {
break;
}
template += element;
}
--num;
} else { //第2步
template += c;
}
}
return template;
}