传送门
大致题意:
输入由p、q、r、s、t、K、A、N、C、E共10个字母组成的逻辑表达式,
其中p、q、r、s、t是逻辑变量,其值为1(true)或0(false);
K、A、N、C、E为逻辑运算符,
K –> and: x && y
A –> or: x || y
N –> not : !x
C –> implies : (!x)||y
E –> equals : x==y
问这个逻辑表达式是否为重言式。并且保证输入格式保证是合法的
解题思路:
p, q, r, s, t不同的取值组合共32种情况,枚举不同取值组合代入逻辑表达式WFF进行计算。
如果对于所有的取值组合,WFF值都为 true, 则结果为 tautology,否则为 not。
WFF的计算方法:
从字符串WFF的末尾开始依次向前读取字符。
构造一个栈stack,当遇到逻辑变量 p, q, r, s ,t 则将其当前的值压栈;
遇到 N 则取栈顶元素进行非运算,运算结果的值压栈;
遇到K, A, C, E则从栈顶中弹出两个元素进行相应的运算,将结果的值压栈。
由于输入是合法的,当字符串WFF扫描结束时,栈stack中只剩一个值,该值就是逻辑表达式WFF的值。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <algorithm>
#define N 500
#define ll long long
using namespace std;
int main(){
#ifndef ONLINE_JUDGE
freopen("1.txt", "r", stdin);
#endif
string str;
bool p, q, r, s, t, tmp1, tmp2;
while(cin >> str) {
if (str == "0"){
break;
}
int i, j, l = str.size();
for (i = 0; i < 32; i++){
stack<char> sta;
p = (i&1);
q = (i&2);
r = (i&4);
s = (i&8);
t = (i*16);
for (j = l-1; j >= 0; j--){
switch(str[j]){
case 'p': sta.push(p); break;
case 'q': sta.push(q); break;
case 's': sta.push(s); break;
case 'r': sta.push(r); break;
case 't': sta.push(t); break;
case 'K': tmp1 = sta.top();
sta.pop();
tmp2 = sta.top();
sta.pop();
sta.push(tmp1&&tmp2);
break;
case 'A': tmp1 = sta.top();
sta.pop();
tmp2 = sta.top();
sta.pop();
sta.push(tmp1||tmp2);
break;
case 'N': tmp1 = sta.top();
sta.pop();
sta.push(!tmp1);
break;
case 'C': tmp1 = sta.top();
sta.pop();
tmp2 = sta.top();
sta.pop();
sta.push((!tmp1)||tmp2);
break;
case 'E': tmp1 = sta.top();
sta.pop();
tmp2 = sta.top();
sta.pop();
sta.push(tmp1==tmp2);
break;
}
}
if (!sta.top()){
break;
}
}
if (i == 32){
cout << "tautology" << endl;
}else{
cout << "not" << endl;
}
}
return 0;
}
部分内容转自http://www.cnblogs.com/lyy289065406/archive/2011/07/29/2120571.html