题意:本题是二叉树的先根遍历,可采用堆栈或递归。给出一个式子,判断是否是永真式,命题有p,q,r,s,t五种,逻辑谓词有K(&),A(|),N(~),C(包含),E(==)五种,我自己是这么理解的用词可能不准确。
思路:构造一个栈,c++现成有,从右往左读输入的字符串,把命题所对应的数据(已经事先生成了,是这些命题的全排列,所有情况组合情况都考虑)压入栈中,每次遇到一个谓词时就取出数据计算,结果再入栈共后边使用。
我这是看的别人写的比较好的代码,我写了注释,转自:http://www.cnblogs.com/yongze103/archive/2010/08/03/1791612.html
| 3295 | Accepted | 208K | 16MS | C++ | 2232B |
#include <iostream>
#include <string>
#include <stack>
#include <cstdio>
#include <cstring>
using namespace std;
stack <bool> sta;
bool val[5], flag;
int main() {
//freopen("poj3295.in", "r", stdin);
int i, j;
string str;
bool tmp1, tmp2;
while(cin >> str && str != "0")
{
flag = 1;
for(i = 0; i<32 && flag; ++i)//i从0-31(00000-11111)
{
memset(val, 0, sizeof(val));
for(j = 0; j<5; ++j)//j从0-4
{
if(i & (1<<j))//(1 << j)的值 分别为10000、01000、00100、00010、00001,下接
val[j] = 1;//和i取“&”后得分贝可以得出p q r s t全排列的每一种情况。建议自己在纸上枚举一下。
}
for(j = str.length() -1; j>=0; --j)
{
switch(str[j])
{
case 'p': case 'q': case 'r': case 's': case 't':
sta.push(val[str[j] - 'p']); break;//事先把每个数据压入栈,使用的时候再取。
case 'N':
tmp1 = sta.top();
sta.pop();
sta.push(!tmp1);
break;
case 'E':
tmp1 = sta.top();
sta.pop();
tmp2 = sta.top();
sta.pop();
sta.push(tmp1 == tmp2);
case 'A':
tmp1 = sta.top();
sta.pop();
tmp2 = sta.top();
sta.pop();
sta.push(tmp1 || tmp2);
break;
case 'K':
tmp1 = sta.top();
sta.pop();
tmp2 = sta.top();
sta.pop();
sta.push(tmp1 && tmp2);
break;
case 'C':
tmp1 = sta.top();
sta.pop();
tmp2 = sta.top();
sta.pop();
if(tmp2 && !tmp1)
tmp1 = 0;
else
tmp1 = 1;
sta.push(tmp1);
break;
default:
break;
}
}
if(!sta.top()) flag = 0;//针对每种情况,如果计算后的结果为0,就不是永真式
}
if(flag) cout << "tautology" << endl;
else cout << "not" << endl;
}
return 0;
}
159

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



