POJ3295
/*
***********************************************************
算法原理:
WFF求值,从表达式的末尾向前读取字符,并分类出入栈。因为输入
是合法的,最后栈顶(且只有一个)的元素即为表达式的逻辑值
Notice:
1)位&运算符的运用,可以精简代码
2)判断K, A, N, C, E的逻辑值可以用已知二维数组
3)还可以用递归求解
***********************************************************
*/
#include<iostream>
#include<stack>
using namespace std;
const int Length = 1000;
stack<int> answers;
char experssion[Length];
int value[5]; //在共2^5(32)种情况下判断
void operaterStack(int pos) //根据expression进行出入栈的操作
{
if (experssion[pos] == 'N')
{
int a = answers.top(); answers.pop();
answers.push(!a);
}
else if (experssion[pos] >= 'p'&&experssion[pos] <= 't')
answers.push(value[experssion[pos] - 'p']); //value[0]-value[4]在32个循环里赋予了不同的值
else
{
int a = answers.top(); answers.pop();
int b = answers.top(); answers.pop();
switch (experssion[pos])
{
case 'K':answers.push(a&&b); break; //或者按题目中给的bool值,用已知数组判断逻辑关系
case 'A':answers.push(a || b); break;
case 'C':answers.push(!a|| b); break;
case 'E':answers.push(a == b); break;
default:break;
}
}
}
int main()
{
while (cin >> experssion&&(experssion != "0")) //表达式结束的标志位'0'
{
int j;
for (j = 0; j < (1 << 5); j++) //共32种情况
{ //详细见图
for (int k = 0; k < 5; k++)
value[k] = j & (1 << k); //类似于x&1判断奇偶
int i = strlen(experssion); //while循环的条件有i--防止越界
while (i--)
operaterStack(i); //value[0]-value[4]在这个函数里发挥作用啦
if (!answers.top())
{
cout << "not\n"; //栈顶元素即为表达式最后的值
answers.pop(); //清空栈,给下一次循环使用
break;
}
}
if (j >= (1 << 5)) //如果j是正常退出,即说明表达式值为1
cout << "tautology\n"; //此时j>=32
}
}
/*
非常酷的用递归的写法,在32个循环中判断即可
int getval()
{
int temp1, temp2;
switch (experssion[pos++])
{
case 'p': return (value & (1 << 0)) ? 1 : 0;
case 'q': return (value & (1 << 1)) ? 1 : 0;
case 'r': return (value & (1 << 2)) ? 1 : 0;
case 's': return (value & (1 << 3)) ? 1 : 0;
case 't': return (value & (1 << 4)) ? 1 : 0;
case 'K': temp1 = getval(); temp2 = getval(); return temp1 & temp2;
case 'A': temp1 = getval(); temp2 = getval(); return temp1 | temp2;
case 'N': return !getval();
case 'C': temp1 = !getval(); temp2 = getval(); return temp1 | temp2;
case 'E': temp1 = getval(); temp2 = getval(); return temp1 == temp2;
}
}
*/