离散数学 命题表达式计算器

本文介绍了一种改进后的代码,用于解析用户输入的命题逻辑表达式,使用模块化设计提高代码可读性。核心功能包括操作符优先级判断、真值计算和表达式合法性检查。

没来得及润色 写的很烂 有时间改成模块化

#include <bits/stdc++.h>
//约定用户用'A'~'Z'作为命题变元 其他的视作非法
using namespace std;
int has_Appeared[26];
bool is_Main_Argument[30000]; 
map<char, int> Value;
set<char> OP{'+', '*', '!', '>', '=', '(', ')', '#'}; //O是操作符的集合 
int In(char c, set<char> OP) {return OP.count(c);} //count 找c出现了多少次
char Precede(char a, char b) {
	switch (a){
		case '!':
			switch(b) {
				case '!': return '>';
				case '*': return '>';
				case '+': return '>';
				case '>': return '> ';
				case '=': return '>';
				case '(': return '<'; //BETA
				case ')': return '>';
				case '#': return '>';
			}
		case '*':
			switch(b) {
				case '!': return '<';
				case '*': return '>';
				case '+': return '>';
				case '>': return '>';
				case '=': return '>';
				case '(': return '<'; //BETA
				case ')': return '>';
				case '#': return '>';
			}
		case '+':
			switch(b) {
				case '!': return '<';
				case '*': return '<';
				case '+': return '>';
				case '>': return '>';
				case '=': return '>';
				case '(': return '<'; //
				case ')': return '>';
				case '#': return '>';
			}
		case '>':
			switch(b) {
				case '!': return '<';
				case '*': return '<';
				case '+': return '<';
				case '>': return '>';
				case '=': return '>';
				case '(': return '<';
				case ')': return '>';
				case '#': return '>';
			}
		case '=':
			switch(b) {
				case '!': return '<';
				case '*': return '<';
				case '+': return '<';
				case '>': return '<';
				case '=': return '>';
				case '(': return '<';
				case ')': return '>';
				case '#': return '>';
			}
		case '(':
			switch(b) {
				case '!': return '<';
				case '*': return '<';
				case '+': return '<';
				case '>': return '<';
				case '=': return '<';
				case '(': return '<';
				case ')': return '=';
				case '#': {cout<<"表达式不合法!";exit(0);}; //undefined
			}
		case ')':
			switch(b) {
				case '!': return '>';
				case '*': return '>';
				case '+': return '>';
				case '>': return '>';
				case '=': return '>';
				case '(': {cout<<"表达式不合法!";exit(0);}; //undefined
				case ')': return '>';
				case '#': return '>';
			}
		case '#':
			switch(b) {
				case '!': return '<';
				case '*': return '<';
				case '+': return '<';
				case '>': return '<';
				case '=': return '<';
				case '(': return '<'; 
				case ')': {cout<<"表达式不合法!";exit(0);}; //undefined
				case '#': return '=';
			}
		 
	}
}
int Operate(int b, char opr ,int a) {
	switch (opr) {
//		case '!': return '<';
		case '*': return b*a;
		case '+': return (a+b)?1:0;
		case '>': return (!b+a)?1:0;    //!b+a
 		case '=': return ((!b+a)?1:0)*((!a+b)?1:0); //(!b+a)*(!a+b)
		case '(': {cout<<"表达式不合法!";exit(0);}; //undefined
		case ')': {cout<<"表达式不合法!";exit(0);}; //undefined
		case '#': {cout<<"表达式不合法!";exit(0);}; //undefined
	}
}
int Operate2(int a) {return !a;};
string AimedValue="";
bool EvaluateExpression() {  //最终return bool 测试版本return int 
	stack<int> OPND; //寄存真值的栈
	stack<char> OPTR; //寄存算符的栈
	OPTR.push('#'); //定义一个运算符# 代表表达式的开始与结束
	int i=0;
	char c;
	c=AimedValue[i++];
	while (c!='#' || OPTR.top()!='#') {
		if (!In(c, OP)) {OPND.push(Value[c]); c=AimedValue[i++]; 
//		cout<<"OPR1"<<endl;
		} //OP是操作符的集合 
		//func 返回命题c对应的当前的真值T of F 
		else {
			switch (Precede(OPTR.top(), c)) {//比较栈顶操作符和当前操作符的优先级 
				case '<': //栈顶元素的优先级比较低
					OPTR.push(c); c=AimedValue[i++];
//					cout<<"OPR2"<<endl;
					break;
				case '=': //托括号
					OPTR.pop(); c=AimedValue[i++];
//					cout<<"OPR3"<<endl;
					break;
				case '>': //计算 入数值栈
//					cout<<"OPR4"<<endl;
				if(OPTR.top()!='!') if(!OPND.size()) {cout<<"表达式不合法!";exit(0);};  //保证栈非空 
				int a=OPND.top(); OPND.pop();
				if(OPTR.top()!='!') {
					if(!OPND.size()) {cout<<"表达式不合法!";exit(0);};
					int b=OPND.top(); OPND.pop();
					OPND.push(Operate(b, OPTR.top(), a));}
				else OPND.push(Operate2(a));
				OPTR.pop();
				break; 
			}
		}
	}
	return OPND.top();
}
int main() {
	cout<<"******************************"<<endl;
	cout<<"*     非 !  合取 *  析取 +   *"<<endl;
	cout<<"*       条件 > 双条件 =      *"<<endl;
	cout<<"*     暂不支持其他连接词!    *"<<endl;
	cout<<"******************************"<<endl; 
	cout<<"请输入您的命题表达式,以#结尾:"; 
	cin>>AimedValue;
	//遍历string 返回常量的个数
	int n=0; //常量个数 
	memset(has_Appeared, 0, sizeof(has_Appeared));
	memset(is_Main_Argument, false, sizeof(is_Main_Argument)); 
	for(int i=0; i<AimedValue.length(); i++) {
		if ('A'<=AimedValue[i] && AimedValue[i]<='Z') {has_Appeared[AimedValue[i]-'A']++; continue;}
		if (In(AimedValue[i], OP)) continue;
		if (AimedValue[i]=='#') continue;
		cout<<"Invalid input"<<endl, exit(0);
	}
	char has_found[26];
	for(int i=0; i<26; i++) if(has_Appeared[i])	has_found[n++]=i+'A'; //计算出了常量的个数
	if (n>15) {cout<<"Too much arguments!"; exit(0);}
	if(n) {	cout<<"您输入了"<<n<<"个命题变元,分别为:"<<endl;
			for(int i=0; i<n; i++) cout<<has_found[i]<<' ';
			cout<<endl; }
	else cout<<"您输入了0个命题变元"<<endl;
	
	
	//检查是否合法
	if(AimedValue[AimedValue.length()-1]!='#') {cout<<"结尾不是#!"<<endl; exit(0);}
	int temp=0;
	for(int j=n-1; j>-1; j--) {
		Value[has_found[j]]=temp%2;
		temp/=2;
	}
	temp=EvaluateExpression();
	//检查完毕 
	cout<<"表达式合法!"<<endl;
	cout<<"真值表:"<<endl; 
	for (int i=0; i<n; i++) cout<<has_found[i]<<"	";
	cout<<"Value"<<endl;
	for(int i=0; i<(1<<n); i++) {
		int temp=i;
		for(int j=n-1; j>-1; j--) {
			Value[has_found[j]]=temp%2;
			temp/=2;
		}
		//真值指派完了 
		for(int j=0; j<n; j++) {
			if (Value[has_found[j]]) cout<<'T'<<"	";
			else cout<<'F'<<"	";
		}
//		输出每一个命题变元的真值
//		cout<<endl;
		temp=EvaluateExpression();
		cout<<"  "<<temp<<"  "<<endl;
	
		if(temp) is_Main_Argument[i]=true; //	输出最后表达式的真值
	}
	cout<<"主析取范式:" ;
	bool first=true;
	for(int i=0; i<(1<<n); i++) { //主吸取 
		if(is_Main_Argument[i]) {
			if(!first) cout<<"+";
			first=false;
			string res="";
			int temp=i;
			for(int j=n-1; j>-1; j--) {
				res[j]=temp%2+'0';
				temp/=2;
			}
			cout<<'(';
			//输出括号里的 
			for(int j=0; j<n-1; j++) {
				if(res[j]=='1') cout<<has_found[j]<<'*';
				else cout<<'!'<<has_found[j]<<'*';
			}
			if(res[n-1]=='1') cout<<has_found[n-1]<<')';
			else cout<<'!'<<has_found[n-1]<<')';
			
		}
	}
	cout<<endl;
	cout<<"主合取范式:" ;
	first=true;
	for(int i=0; i<(1<<n); i++) { //主合区 
		if(!is_Main_Argument[i]) {
			if(!first) cout<<"*";
			first=false;
			string res="";
			int temp=i;
			for(int j=n-1; j>-1; j--) {
				res[j]=temp%2+'0';
				temp/=2;
			}
			cout<<'(';
			//输出括号里的 
			for(int j=0; j<n-1; j++) {
				if(res[j]=='0') cout<<has_found[j]<<'+';
				else cout<<'!'<<has_found[j]<<'+';
			}
			if(res[n-1]=='0') cout<<has_found[n-1]<<')';
			else cout<<'!'<<has_found[n-1]<<')';
			
		}
	}
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值