【离散数学编程】输入一个0、1和命题联结词的复合命题,自动判断整体表达式真假(包含c语言代码)
简述
输入一个0和1组成的表达式去判断真假,无论如何输入的总是一个表达式,并且都存在一个“运算符”优先级的问题,自然而然地会想到之前用栈写的表达式求值。
此处放下链接:
表达式求值(栈)问题详解
对于复合命题,常用的命题联结词有(按照优先级顺序排列)有:
非、合取、析取、蕴含词、等值词
简单复习一下:
非:
1的非就是0 0的非就是1
合取:
1 and 1=1 1 and 0=0 0 and 0=0
析取:
1 or 1=1 1 or 0=1 0 or 0=0
蕴含:
a蕴含b时,只有 a真b假才为假,其它均为真
等值:
a等值b时,只有ab同真同假为真,其它为假
准备工作
大方向实际就是表达式求值的方法,只需要在几个方面进行修改即可
1.整数处理:
在表达式求值中,由于是一个字符一个字符地处理,所以,对于位数大于1的整数,需要利用一个函数去处理之后再入栈并进行后续运算,但是在这里比较简单,因为0表示假,1表示真,只有1位数
2.运算符处理:
对于运算符优先级,我们仿照表达式求值中的加减乘除,依次重新定义五大命题联结词,在此处,我们定义:^表示非,*表示合取,+表示析取,-表示蕴含,=表示等值。
根据它们优先级,去绘制一个优先级表格,并写入函数“precede(char a,char b)”中:

代码实现
//大写字母表示命题
//整型代替布尔型 0假1真
//表达式就后面有#号,前面不用
//命题联结词优先级:
//非 ^ 合取* 析取 + 蕴含- 等值 = 支持使用括号
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OK 2
#define OVERFLOW 0
#include
#include
#include
#include
typedef int Status;
int my_and(int A,int B)//合取
{return A&&B;
}
int my_or(int A,int B)//析取
{return A||B;
}
int my_not(int A)//非
{return !A;
}
int implied(int A,int B)//蕴含
{return !A||B;
}
int exclusive_or(int A,int B)//异或
{return (A&&!B)||(!A&&B);
}
int equivalent(int A,int B)//等值
{return (A&&B)||(!A&&!B);
}
typedef struct NumStackNode{int data;struct NumStackNode* next;
}NumStackNode,*NumStackNodePtr;
typedef struct{NumStackNodePtr top;NumStackNodePtr bottom;
}NumStack,*NumStackPtr; //数字栈 存放0或1代替命题真值
typedef struct CharStackNode{char data;struct CharStackNode *next;
}CharStackNode,*CharStackNodePtr;
typedef struct{CharStackNodePtr top;CharStackNodePtr bottom;
}CharStack,*CharStackPtr; //字符栈 存放命题联结词
NumStackPtr NumInitStack(void);//初始化数字栈
CharStackPtr CharInitStack(void);//初始化字符栈
Status NumGetTop(NumStackPtr S,int* e);//取数字栈栈顶
Status CharGetTop(CharStackPtr S,char* e);//取字符栈栈顶
Status NumPush(NumStackPtr S,int e);//数字栈入栈
Status CharPush(CharStackPtr S,char e);//字符栈入栈
Status NumPop(NumStackPtr S,int *e);//数字栈出栈
Status CharPop(CharStackPtr S,char *e);//字符栈出栈
Status isOPTR(char c);//判断是不是联结词
char Precede(char c1,char c2);//比较优先级
int Operate(int a,char sign,int b);//运算
bool EvaluateExpression();//表达式求值
int main()
{bool flag;printf("输入表达式:");flag=EvaluateExpression();if(flag)printf("真");elseprintf("假");return 0;
}
NumStackPtr NumInitStack(void)
{NumStackPtr S=(NumStackPtr)malloc(sizeof(NumStack));S->bottom=S->top=(NumStackNodePtr)malloc(sizeof(NumStackNode));if(S->bottom==NULL)exit(OVERFLOW);else return S;
}
CharStackPtr CharInitStack(void)
{CharStackPtr S=(CharStackPtr)malloc(sizeof(CharStack));S->bottom=S->top=(CharStackNodePtr)malloc(sizeof(CharStackNode));if(S->bottom==NULL)exit(OVERFLOW);else return S;
}
Status NumGetTop(NumStackPtr S,int *e)
{if(S->bottom==S->top) return ERROR; *e=S->top->data;return OK;
}
Status CharGetTop(CharStackPtr S,char *e)
{if(S->bottom==S->top) return ERROR; *e=S->top->data;return OK;
}
Status NumPush(NumStackPtr S,int e)
{NumStackNodePtr pNew=(NumStackNodePtr)malloc(sizeof(NumStackNode));pNew->data=e;pNew->next=S->top;S->top=pNew;return OK;
}
Status CharPush(CharStackPtr S,char e)
{CharStackNodePtr pNew=(CharStackNodePtr)malloc(sizeof(CharStackNode));pNew->data=e;pNew->next=S->top;S->top=pNew;return OK;
}
Status NumPop(NumStackPtr S,int *e)
{if(S->bottom==S->top) return ERROR;*e=S->top->data;NumStackNodePtr p=S->top;S->top=S->top->next;free(p);p=NULL;//避免野指针
}
Status CharPop(CharStackPtr S,char *e)
{if(S->bottom==S->top) return ERROR;*e=S->top->data;CharStackNodePtr p=S->top;S->top=S->top->next;free(p);p=NULL;//避免野指针
}
//非 ^ 合取* 析取+ 蕴含- 等值 = 优先级从左到右
Status isOPTR(char c)
{if(c=='^'||c=='*'||c=='+'||c=='-'||c=='('||c==')'||c=='#'||c=='=')return TRUE;else return FALSE;
}
char Precede(char c1,char c2)
{switch(c1){case '^':if(c2=='(')return '<';else return '>';case '*':if(c2=='('||c2=='^')return '<';else return '>';case '+':if(c2=='('||c2=='^'||c2=='*')return '<';elsereturn '>';case '-':if(c2=='('||c2=='^'||c2=='*'||c2=='+')return '<';elsereturn '>';case '=':if(c2=='='||c2==')'||c2=='#')return '>';elsereturn '<';case '(':if(c2==')')return '=';elsereturn '<';case ')':return '>';case '#':if(c2=='#')return '=';elsereturn '<';default:printf("格式错误\n");return ERROR; }
}
int Operate(int a,char sign,int b)//仅包含了双目运算符,不包含非操作,非操作将单独分类
{switch(sign){case '*':return my_and(a,b);case '+':return my_or(a,b);case '-':return implied(a,b);case '=':return equivalent(a,b);}
}
bool EvaluateExpression()
{NumStackPtr OPND=NumInitStack();CharStackPtr OPTR=CharInitStack();CharPush(OPTR,'#');char c=getchar();char temp1; CharGetTop(OPTR,&temp1); char sign;int temp;int a,b;while(c!='#'||temp1!='#'){if(!isOPTR(c))//不是运算符则进栈 {NumPush(OPND,c-'0');c=getchar();}else{CharGetTop(OPTR,&temp1);switch(Precede(temp1,c)){case '<':CharPush(OPTR,c);c=getchar();break;case '=':CharPop(OPTR,&temp1);c=getchar();break;case '>':CharPop(OPTR,&sign);if(sign=='^'){NumPop(OPND,&a);NumPush(OPND,my_not(a));}else{NumPop(OPND,&a);NumPop(OPND,&b);NumPush(OPND,Operate(a,sign,b));}break;}}CharGetTop(OPTR,&temp1);}NumGetTop(OPND,&temp);if(temp)return true;elsereturn false;
}
效果展示:


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
