题目链接
http://poj.org/problem?id=3295
题目大意
离散数学里面的基本操作,K, A, N, C, E 代表and, or, not ,implies 和equals
然后给出一个复合式子,判断是否是重言式(即永真式)
题目分析
该题目就是简单的逻辑运算式的计算,能正确地算出最终结果就算成功。
一共五个字母pqrst。
包含这五个字母的逻辑表达式一共有2的五次方种计算情况,即00000~11111.
如果在所有的情况下结果均为1,则输出tautology,过程中一旦结果不为1,则输出not.
int i=0;
for(;i<(1<<5);i++)
用栈模拟代码如下:
#include<iostream>
#include<stack>
#include<string.h>
using namespace std;
int p,q,r,s,t;
bool value[5];//int和bool可以互相转化,这里用bool更加合适
int main()
{
string str;
while(cin>>str&&str[0]!='0'){
/*
对于p,q,r,s,t一共有2的五次方种情况
即00000~11111
*/
stack<int>Q;
int i=0;
for(;i<(1<<5);i++)
{
for(int k=4;k>=0;k--)
value[k]=i&(1<<(4-k));
for(int j=str.length()-1;j>=0;j--)
{
if(str[j]>='p'&&str[j]<='t')
{
Q.push(value[str[j]-'p']);
}
else if(str[j]=='N')
{
int it=Q.top();
Q.pop();
Q.push(!it);
}
else
{
int x=Q.top();Q.pop();
int y=Q.top();Q.pop();
switch(str[j])
{
case 'K':Q.push(x&&y);break;//与运算式两个&符号
case 'A':Q.push(x||y);break;
case 'C':Q.push(!x||y);break;
case 'E':Q.push(x==y);break;
default:break;
}
}
}
if(!Q.top())
{
cout<<"not"<<endl;
Q.pop();
break;
}
}
if(i==(1<<5))
cout<<"tautology"<<endl;
}
}
简单递归方式:
递归和上面的栈区别为:
- 递归自顶向下,而栈是自底向上
- 递归实现简单,但是开销太大
int ss()
{
char ch=s[l++];
printf("");
switch(ch)
{
case 'p':
case 'q':
case 'r':
case 's':
case 't':
return state[ch-'p'];
break;
case 'K':
return ss()&ss();
break;
case 'A':
return ss()|ss();
break;
case 'N':
return !ss();
break;
case 'C':
return !ss()|ss();
break;
case 'E':
return ss()==ss();
break;
}
}