【离散数学编程】输入一个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<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
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("真");
    else
    printf("假");
	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 '<';
			else
			return '>';
		case '-':
			if(c2=='('||c2=='^'||c2=='*'||c2=='+')
			return '<';
			else
			return '>';
		case '=':
			if(c2=='='||c2==')'||c2=='#')
			return '>';
			else
			return '<';
		case '(':
			if(c2==')')
			return '=';
			else
			return '<';
		case ')':
			return '>';
		case '#':
			if(c2=='#')
			return '=';
			else
			return '<';
		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;
    else
    return false;
}

 效果展示:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值