该题的意思就是:给你一个表达式,判断它是否为永真式,若是输出tautology,否输出not。
解题步骤:1.根据题内所示表格构造K,A,N,C,E的运算
2.枚举p,q,r,s,t的32种情况
3.表达式的计算
注意事项:1.表达式为前置表达式,需从数组末尾开始遍历
2.全局变量每循环一次需重置
ps:p,q,r,s,t的存储可用数组实现也可用map实现
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <map>
using namespace std;
char a[110];
int num[5];
int sign=1;//标记是否均符合要求
stack <int> cal;//运算栈
int len;
int calculate()//前缀表达式的运算
{
int m,n;
while(!cal.empty())
cal.pop();
for(int i=len-1;i>=0;i--)
{
if(a[i]=='p')//操作数部分
cal.push(num[0]);
else if(a[i]=='q')
cal.push(num[1]);
else if(a[i]=='r')
cal.push(num[2]);
else if(a[i]=='s')
cal.push(num[3]);
else if(a[i]=='t')
cal.push(num[4]);
else//操作符部分
{
m=cal.top();//取最顶上一个操作数,因为有非运算所以只取一个
cal.pop();
if(a[i]=='N')
cal.push(!m);
else
{
n=cal.top();
cal.pop();
if(a[i]=='K')
cal.push(m&&n);
else if(a[i]=='A')
cal.push(m||n);
else if(a[i]=='C')
{
if(m==1&&n==0)
cal.push(0);
else
cal.push(1);
}
else if(a[i]=='E')
{
if(m==n)
cal.push(1);
else
cal.push(0);
}
}
}
}
return cal.top();
}
int main()
{
while(cin.getline(a,110))
{
if(a[0]=='0')
break;
len=strlen(a);
for(int p=0;p<2&&sign;p++)
{
num[0]=p;
for(int q=0;q<2&&sign;q++)
{
num[1]=q;
for(int r=0;r<2&&sign;r++)
{
num[2]=r;
for(int s=0;s<2&&sign;s++)
{
num[3]=s;
for(int t=0;t<2&&sign;t++)
{
num[4]=t;
if(calculate()==0)
sign=0;
}
}
}
}
}
if(!sign)
cout<<"not"<<endl;
else
cout<<"tautology"<<endl;
sign=1;
}
return 0;
}