主析取范式(基于真值表计算)-C语言

【问题描述】

请根据给定的命题公式,计算其真值为T的小项,列出主析取范式,并输出结果。

【输入形式】

输入一个字符串(字符串长度<=50)形式的命题公式,以回车表示输入结束。其中的命题公式为仅包含原子命题、联结词和括号的合式公式。联结词仅包含下述5中联结词:

1、否定,表示为“!”

2、合取,表示为“*”

3、析取,表示为“|”

4、条件,表示为“-”

5、双条件,表示为“=”

例如:

(P-Q)-R

注意:输入符号均采用英文输入。

【输出形式】

输出一个以单个空格分隔的字符串,字符串中各项分别对应主析取范式中小项的序号。

如(P-Q)- R对应的小项为

则输出1 3 4 5 7

注意:其中的原子命题按字母表排序。

【样例输入】

(P-Q)- R

【样例输出】

1 3 4 5 7
本方法涉及栈的应用,经过本人测试正确
代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define STACK_INIT_SIZE 100//存储空间初始分配量
#define STACKINCREMENT 10//存储空间分配增量
char str[100],s[100],b[100],c[100];
int n=0;
typedef int Status;
typedef char SElemType;
typedef struct
{
    SElemType  * base;
    SElemType  * top;
    int stacksize;
}SqStack;
Status InitStack(SqStack &S){
    S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
    if(!S.base)exit(OVERFLOW);
    S.top=S.base;
    S.stacksize=STACK_INIT_SIZE;
    return OK;
}
Status StackEmpty(SqStack &S){
    if(S.base!=S.top)
        return TRUE;
    else return FALSE;
}
char GetTop(SqStack &S){
    char e;
    if(S.base == S.top)return ERROR;
    e=*(S.top-1);
    return e;
}
Status Push(SqStack &S,SElemType e){    //进栈
        if(S.top-S.base>=S.stacksize){
        S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)* sizeof(SElemType));
        if(!S.base)exit(OVERFLOW);
        S.top=S.base+S.stacksize;
        S.stacksize+=STACKINCREMENT;
    }
    * S.top++=e;
}
Status Pop(SqStack &S,SElemType &e){
    if(S.top== S.base)return ERROR;
    else e= * --S.top;
}
int in(char a)//入栈
{
    switch (a){
    case '#':return 0;break;
    case '(':return 12;break;
    case '!':return 10;break;
    case '* ':return 8;break;
    case '|':return 6;break;
    case '-':return 4;break;
    case '=':return 2;break;
    case ')':return 1;break;
    }
}
int out(char a)//出栈
{
    switch(a)
    {
    case '#':return 0;break;
    case '(':return 1;break;
    case '!':return 11;break;
    case '* ':return 9;break;
    case '|':return 7;break;
    case '-':return 5;break;
    case '=':return 3;break;
    case ')':return 12;break;
    }
}
void swi(char e,SqStack &S2)
{
    char e1,e2;
    e1=GetTop(S2);e1=e1-'0';
    if(e=='!')
    {
        if(e1)  * (S2.top-1)='0';
        else  * (S2.top-1)='1';return;
    }
    e2= * (S2.top-2);e2=e2-'0';
    switch(e){
    case '*':if(e1&&e2) *(S2.top-2)='1';
             else  *(S2.top-2)='0';
             Pop(S2,e1);break;
    case '|':if(e1||e2) *(S2.top-2)='1';
             else *(S2.top-2)='0';
             Pop(S2,e1);break;
    case '-':if(!e2||e1) *(S2.top-2)='1';
             else  *(S2.top-2)='0';
             Pop(S2,e1);break;
    case '=':if(e1 == e2) *(S2.top-2)='1';
             else  *(S2.top-2)='0';
             Pop(S2,e1);break;
    }
}
int num()
{
    int i,sum=0;
    for(i=0;i<n;i++)
        sum=sum+(c[i]-'0')*pow(2,n-i-1);
    return sum;
}
void fun()
{
    int i,j,flag=0;char x,e;SqStack S1,S2;
    InitStack(S1);InitStack(S2);
    Push(S1,'#');
    for(i=0;str[i]!='\n';i++)
    {
        if(!((str[i]>='A'&&str[i]<='Z')||(str[i]>='a'&&str[i]<='z')))
        {s[i]=str[i];continue;}
        for(j=0;j<n;j++)
          if(str[i]= =b[j])
            {s[i]=c[j];}
    }
    i=0;
    while(s[i]!='#'||GetTop(S1)!='#')
    {
        if(s[i]= = '0'||s[i]= ='1'){Push(S2,s[i]);i++;}
        else
        {
            if(out(GetTop(S1))<in(s[i]))
            {
                Push(S1,s[i]);i++;
            }
            else if(out(GetTop(S1))= =in(s[i]))
            {
                Pop(S1,x);i++;
         }
            else
            {
                Pop(S1,e);
                swi(e,S2);
            }
        }
    }
    e=GetTop(S2);
    flag=e-'0';
    if(flag)
       printf("%d ",num());
}
void dip(int k)
{
    if(k==n){
            fun();
            return;}
    else {
        c[k]='0';dip(k+1);
        c[k]='1';dip(k+1);
    }
}
int main()
{
    scanf("%s",str);int i,j=0,k,m=1;
    for(i=0;str[i];i++)
        if((str[i]>='A'&&str[i]<='Z')||(str[i]>='a'&&str[i]<='z'))
          {
              for(k=0;k<j;k++)
                  if(str[i]==b[k]) m=0;
              if(m ==1)b[j++]=str[i];
              m=1;
          }
    n=j;
    str[i]='#';
    str[i+1]='\n';
    dip(0);
    printf("\n");
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值