poj3295-Tautology

18 篇文章 0 订阅
5 篇文章 0 订阅

/*大致题意:
输入由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:输入格式保证是合法的
解题思路:
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<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct 
{
 int str[105];
 int top;
}stack,*pstack;
int pp,qq,rr,ss,tt;
pstack init_stack()
{//创建栈,初始化 
 pstack p;
 p=(pstack)malloc(sizeof(stack));
 if(p)
   p->top=-1;
 return p;
}
int push_stack(pstack s,int x)
{//压栈,将x压入栈中 
     s->top++;
     s->str[s->top]=x;
     return 1;
}
int pop_stack(pstack s,int *x)
{//弹栈,并保存在x中 
 if(s->top==-1)
     return 0;
 else
 {
  *x=s->str[s->top];
  s->top--;
  return 1;
 }
}
void destroy_stack(pstack s)
{//销毁栈 
   s->top=-1;
}
int K(int x,int y)
{
 return x&&y;
}
int A(int x,int y)
{
 return x||y;
}
int C(int x,int y)
{
 return (!x)||y;
}
int E(int x,int y)
{
 return x==y;
}
int N(int x)
{
 return !x;
}
int isvariable(pstack s,char ch)
{//判断是否是变量 
 switch(ch)
 {
  case  'p':push_stack(s,pp);return 1;
  case  'q':push_stack(s,qq);return 1;
  case  'r':push_stack(s,rr);return 1;
  case  's':push_stack(s,ss);return 1;
  case  't':push_stack(s,tt);return 1;
 } 
 return 0;
}
void  operators(pstack s,char op)
{
 int x,y;
 switch(op)
 {
  case 'K':
   {
       pop_stack(s,&x);
    pop_stack(s,&y);
    push_stack(s,K(x,y));
    break; 
   }
  case 'A':
   {
    pop_stack(s,&x);
    pop_stack(s,&y);
    push_stack(s,A(x,y));
    break;
   }
  case 'C':
   {
      pop_stack(s,&x);
      pop_stack(s,&y);
      push_stack(s,C(x,y));
      break; 
   }
  case 'E':
   {
    pop_stack(s,&x);
    pop_stack(s,&y);
    push_stack(s,E(x,y));
             break;
   }
  case 'N':
      {
      pop_stack(s,&x);
      push_stack(s,N(x));
      break;
      } 
 }
 return ;
} 
int main()
{
 char wff[105];
 //int pp,qq,rr,ss,tt;
 while(scanf("%s",wff)&&wff[0]!='0')
 {
  pstack s;
     s=init_stack();
  getchar();
  int flag=1;
  int len=strlen(wff);
  for(pp=0;pp<=1;pp++)  //枚举逻辑变量的值
  {
   for(qq=0;qq<=1;qq++)
   {
    for(rr=0;rr<=1;rr++)
    {
     for(ss=0;ss<=1;ss++)
     {
      for(tt=0;tt<=1;tt++)
      {
       for(int pw=len-1;pw>=0;pw--)
       {
        if(!isvariable(s,wff[pw]))
         operators(s,wff[pw]);
       }
       int ans=s->str[s->top];   //最后栈剩一个值,即为逻辑表达式的值
       if(!ans)  //只要表达式有一个值为假,它就不是永真式
       {
        flag=0;
        break;
       }
       destroy_stack(s);
      }
      if(!flag)
       break;
     }
     if(!flag)
      break;
    }
    if(!flag)
     break;
   }
   if(!flag)
    break;
  }
  if(flag)
   printf("tautology\n");
  else
   printf("not\n");
 }
 return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值