又是一道题搞了一个晚上。。各中滋味难以言表,无限WA。。。开始用C,是先转后缀表达式再求值的,逻辑有错误,我以为栈哪里用错了,换JAVA搞,一样的算法,Runtime Error了,肯定是抛空栈异常了,肯定有比较变态的测试数据。。翻了翻大牛的题解,说有!!!!V这种数据,好吧,一运行果断报错了,然后就慢慢改,对于取反操作的处理和其他两个不大一样,和括号的处理有点像,就是如果读入一个数字,就判断前面是否有取反符号,直接算掉,还有就是当一个括号计算完之后,如果前面有取反符号,还是先把取反符号的操作算掉。。还好最后逻辑总算对了,真艰难啊。。
import java.util.Scanner;
import java.util.Stack;
public class Main
{
static boolean convert(String s)
{
Stack<Character> op = new Stack<Character>();
Stack<Boolean> num = new Stack<Boolean>();
for (char c : s.toCharArray())
{
if (c == ' ')
continue;
else if (c == 'F' || c == 'V')
{
num.push(c == 'V');
while (!op.isEmpty() && op.peek() == '!')
calc(num, op.pop());
}
else if (c == '(' || c == '!')
op.push(c);
else if (c == ')')
{
while (op.peek() != '(')
calc(num, op.pop());
op.pop();
while (!op.isEmpty() && op.peek() == '!')
calc(num, op.pop());
}
else if (c == '|')
{
while (!op.isEmpty() && op.peek() != '(')
calc(num, op.pop());
op.push(c);
}
else if (c == '&')
{
while (!op.isEmpty() && op.peek() != '(' && op.peek() != '|')
calc(num, op.pop());
op.push(c);
}
}
while (!op.isEmpty())
calc(num, op.pop());
return num.pop();
}
static void calc(Stack<Boolean> num, char op)
{
boolean a, b;
if (op == '!')
{
a = num.pop();
num.push(!a);
}
else if (op == '|')
{
a = num.pop();
b = num.pop();
num.push(a || b);
}
else
{
a = num.pop();
b = num.pop();
num.push(a && b);
}
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int count = 0;
while (sc.hasNextLine())
{
String line = sc.nextLine();
System.out.format("Expression %d: %s\n", ++count,
convert(line) ? "V" : "F");
}
sc.close();
}
}