借助的是这位大神的解题报告的写法,不愿多敲了。
大致题意:
输入由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
问这个逻辑表达式是否为永真式。
PS:输入格式保证是合法的。
代码操作:
1、把变量(p,q,r,s,t)替换成0,1。(替换有规律,见数组num,共32中可能);
2、用栈将字符串倒序当后缀式运算。
3、判断运算完成后栈底元素是否为1,如果不为0跳出输出not。
4、若32种可能都为1,则输出tautology;以下是代码:
#include <stdio.h>
#include <string.h>
int main()
{
char s[105],s1[105],z[105];
int top,flat,i,j,k,p;
int num[32][5]=
{
1,1,1,1,1,
1,1,1,1,0,
1,1,1,0,1,
1,1,1,0,0,
1,1,0,1,1,
1,1,0,1,0,
1,1,0,0,1,
1,1,0,0,0,
1,0,1,1,1,
1,0,1,1,0,
1,0,1,0,1,
1,0,1,0,0,
1,0,0,1,1,
1,0,0,1,0,
1,0,0,0,1,
1,0,0,0,0,
0,1,1,1,1,
0,1,1,1,0,
0,1,1,0,1,
0,1,1,0,0,
0,1,0,1,1,
0,1,0,1,0,
0,1,0,0,1,
0,1,0,0,0,
0,0,1,1,1,
0,0,1,1,0,
0,0,1,0,1,
0,0,1,0,0,
0,0,0,1,1,
0,0,0,1,0,
0,0,0,0,1,
0,0,0,0,0,
};
while(scanf("%s",s),s[0]!='0')
{
flat=1;
p=strlen(s);
for(k=0;k<32;k++)
{
top=0;
for(i=0;i<p;i++)
{
switch(s[i])
{
case 'p':s1[i]=num[k][0]+'0';break;
case 'q':s1[i]=num[k][1]+'0';break;
case 'r':s1[i]=num[k][2]+'0';break;
case 's':s1[i]=num[k][3]+'0';break;
case 't':s1[i]=num[k][4]+'0';break;
default:s1[i]=s[i];break;
}
}
for(i=p-1;i>=0;i--)
{
if(s1[i]=='0'||s1[i]=='1')
{
z[top]=s1[i];
top++;
}
else if(s1[i]=='K')
{
z[top-2]=((z[top-2]-'0')&&(z[top-1]-'0'))+'0';
top--;
}
else if(s1[i]=='A')
{
z[top-2]=((z[top-2]-'0')||(z[top-1]-'0'))+'0';
top--;
}
else if(s1[i]=='C')
{
z[top-2]=((!(z[top-2]-'0'))||(z[top-1]-'0'))+'0';
top--;
}
else if(s1[i]=='E')
{
z[top-2]=((z[top-2]-'0')==(z[top-1]-'0'))+'0';
top--;
}
else if(s1[i]=='N')
{
z[top-1]=(!(z[top-1]-'0'))+'0';
}
}
if(z[0]=='0')
{
flat=0;
break;
}
}
if(flat)
{
printf("tautology\n");
}
else
{
printf("not\n");
}
}
return 0;
}