一、 思路分析
通过构造栈,并使用枚举的方法实现功能。对p、q、r、s、t五个变量分别取0或1的一共2^5种情况进行枚举,从字符串末尾开始,每遇到一个变量就转化为0、1的int型数据进栈,每遇到K、A、C、E五个逻辑词,就出栈2个逻辑变量,每遇到N逻辑词,就出栈1个变量,进行逻辑运算后再把结果进栈,最后栈底剩下的元素即为运算的结果。只要在2^5种情况中出现一种情况不符合永真的结果,就跳出循环,输出“not”;如全部符合真,则输出“tautology”。
二、 方法设计及性能衡量
1、构造一个int数据类型的栈IntVarStack,用来存放已经转换为0、1的逻辑值
2、定义全局变量p、q、r、s、t(int):五个逻辑变量
ss(string):输入的字符串 len(int):字符串长度
3、函数Input(char c):将逻辑变量转变为0和1的逻辑值进栈,并返回1,若是逻辑词则返回0
4、函数Fun(char c):用switch,如果是K、A、C、E逻辑词,则出栈两个元素进行逻辑运算,将结果再进栈,如果是N逻辑词,则出栈一个元素进行逻辑运算,将结果再进栈。
5、在主函数用枚举的方法,对所有逻辑变量的不同取值进行逐一运算,如果出现不是真的情况,就输出“not”,若是永真,则输出“tautology”
三、代码实现
#include<iostream>
#include<cstring>
#include<string>
#include<stack>
using namespace std;
stack<int> IntVarStack;
int p,q,r,s,t;
string ss;
int len;
int Input(char c)
{
switch(c)
{
case 'p':IntVarStack.push(p);return 1;
case 'q':IntVarStack.push(q);return 1;
case 'r':IntVarStack.push(r);return 1;
case 's':IntVarStack.push(s);return 1;
case 't':IntVarStack.push(t);return 1;
}
return 0;
}
//对逻辑变量进行判断,将逻辑变量对应的逻辑值入栈
void Fun(char c)
{
switch(c)
{
case 'K':
{
int a=IntVarStack.top();
IntVarStack.pop();
int b=IntVarStack.top();
IntVarStack.pop();
IntVarStack.push(a&&b);
break;
}
case 'A':
{
int a=IntVarStack.top();
IntVarStack.pop();
int b=IntVarStack.top();
IntVarStack.pop();
IntVarStack.push(a||b);
break;
}
case 'C':
{
int a=IntVarStack.top();
IntVarStack.pop();
int b=IntVarStack.top();
IntVarStack.pop();
IntVarStack.push((!a)||b);
break;
}
case 'E':
{
int a=IntVarStack.top();
IntVarStack.pop();
int b=IntVarStack.top();
IntVarStack.pop();
IntVarStack.push(a==b);
break;
}
case 'N':
{
int a=IntVarStack.top();
IntVarStack.pop();
IntVarStack.push(!a);
break;
}
}
}
//对逻辑词进行判断,出栈相应数量的逻辑值进行逻辑运算,再把结果入栈
int main()
{
while(cin>>ss&&ss!="0")
{
int flag=1;
//用flag判断是否出现不是真的情况
len=ss.length();
for(p=0;p<=1;p++)
{
for(q=0;q<=1;q++)
{
for(r=0;r<=1;r++)
{
for(s=0;s<=1;s++)
{
for(t=0;t<=1;t++)
{
for(int i=len-1;i>=0;i--)
{
if(!Input(ss[i]))
Fun(ss[i]);
}
//对字符串内所以元素从末向前遍历,如果是逻辑变量,则转化为相应逻辑值入栈,如果是逻辑词,则进入Fun函数进行逻辑运算。
int last=IntVarStack.top();
IntVarStack.pop();
//必须把栈里的最后一个元素出栈清空,才能循环利用到下一情况
if(!last)
{
flag=0;
break;
}
}
if(!flag)
break;
}
if(!flag)
break;
}
if(!flag)
break;
}
if(!flag)
break;
}
//对所有逻辑变量的取值进行枚举
if(flag)
cout<<"tautology"<<endl;
else
cout<<"not"<<endl;
}
return 0;
}