如果能转换为 逆波兰 表达式,那么每次遇到操作符,弹出两个数运算即可
关于如何转 逆波兰 表达式:
1.如果遇到操作数,则直接输出。
2.如果遇到操作符,则检查栈顶元素优先级,如果其优先级不低于当前操作符(左括号除外),则弹出栈顶元素并输出。重复此过程直到栈顶元素优先级小于当前操作符或为左括号,或者栈为空。 然后将当前操作符压入栈中。
3.如果遇到左括号,直接压入栈中。
4. 如果遇到右括号,则将栈中元素弹出,直到遇到左括号为止。左括号只弹出栈而不输出。
5.表达式处理完毕,则将栈中元素依次弹出。
注意只有遇到右括号的情况下才会弹出左括号,其他情况都不会弹出。
实际在计算的过程中,给定字符,可以不转为 逆波兰,借助这个思路,用两个栈直接计算
package Myself;
import java.util.Stack;
class Test77{
public int calculate(String s)
{
int n = s.length();
Stack<Integer> s1 = new Stack<>();
Stack<Character>s2 = new Stack<>();
for (int i=0;i<n;i++)
{
char c = s.charAt(i);
if (c==' ')continue;
if (c=='+' || c=='-' )
{
if (s2.isEmpty() || s2.peek()=='(')
{
s2.push(c);
}
else {
compute(s1,s2); // 第一次算
s2.push(c);
}
}
else if ( c=='*' || c=='/' || c=='(')
{
s2.push(c);
}
else if (c==')') // 第二次算
{
compute(s1,s2);
s2.pop();
}
else if (Character.isDigit(c)){
int t = c - '0';
while (i+1<n && Character.isDigit(s.charAt(i+1) )) // 数字大于10
{
t = t*10 + s.charAt(i+1) - '0';
i++;
}
s1.push(t);
}
}
compute(s1,s2); // 第三次算
return s1.peek();
}
public void compute(Stack<Integer>s1,Stack<Character>s2)
{
while (true)
{
if(s2.isEmpty() || s2.peek()=='(')break;
char operator = s2.pop();
int a = s1.pop();
int b = s1.pop();
int ans = 0;
if (operator=='*')
{
ans = b * a;
}
else if (operator=='/')
{
ans = b/a;
}
else if (operator=='+')
{
ans = b + a;
}
else if (operator=='-')
{
ans = b - a;
}
//System.out.println(String.format("s1.push: %d",ans));
s1.push(ans);
}
}
}
public class V77 {
public static void main(String[] args) {
Test77 test = new Test77();
// String str = "2+3*5-9/2";
// String str = "3-10/8+5*2";
// String str = "1*(3-2-1)+1";
String str = "(1+(4+5+2)-3)+(6+8)";
int ans = test.calculate(str);
System.out.println(ans);
}
}
4079

被折叠的 条评论
为什么被折叠?



