Loading

函数实现复合命题的计算及判断两个命题是否等值——中缀表达式转后缀表达式

主要是中缀转后缀+构造真值表进行判断,借助map来进行映射。

#include <iostream>
#include <stack>
#include <map>
#include <vector>
using namespace std;
int n/*变元个数*/;
map<char, int> mp;//映射变元和其值
map<char, int> priority;//映射操作符优先级
string s;//表达式
string ss = "";//转化过来的后缀表达式
bool TruthTable1[1 << 8][26] = { 0 }, TruthTable2[1 << 8][26] = { 0 };
vector<char> v;//存储变元
int fpow(int a, int b)
{
	int ans = 1;
	for(; b; b >>= 1)
	{
		if(b & 1) ans = ans * a;
		a = a * a;
	}
	return ans;
}
void init()
{
	//priority['!'] = 4;
	priority['&'] = 3;
	priority['|'] = 2;
	priority['>'] = 1;//蕴含
	priority['~'] = 0;//等值
	priority['('] = -1;
}
void work1()
{
	stack<char> op;//存储运算符的栈
	for(int i = 0; i < s.size(); i++)
	{
		if(s[i] >= 'A' && s[i] <= 'Z' || s[i] >= 'a' && s[i] <= 'z')//遇到变量直接输出该数(加到ss上)
		{
			ss = ss + s[i];
		}
		else if(s[i] == '(') op.push(s[i]);
		else if(s[i] == ')')
		{
			while(op.size() && op.top() != '(')
			{
				char now = op.top();
				op.pop();
				ss = ss + now;//不断累加到后缀表达式
			}
			op.pop();//左括号出栈
		}
		else
		{
			//char now = op.top();//栈顶
			while(op.size() && priority[op.top()] >= priority[s[i]])//只要栈顶符号的优先级不低于新符号,就不断取出栈顶并更新后缀表达式 最后把新符号入栈
			{
				ss = ss + op.top();
				op.pop();
			}
			op.push(s[i]);
		}
	}
	while(op.size())
	{
		ss += op.top();
		op.pop();
	}
}
int work2()
{
	stack<bool> num;//用于存数的栈
	for(int i = 0; i < ss.size(); i++)
	{
		if(ss[i] >= 'A' && ss[i] <= 'Z' || ss[i] >= 'a' && ss[i] <= 'z')
		{
			num.push(mp[ss[i]]);
		}
		else//遇到运算符
		{
			bool y = num.top();
			num.pop();
			bool x = num.top();
			num.pop();
			if(ss[i] == '&')
			{
				num.push(x & y);
			}
			else if(ss[i] == '|')
			{
				num.push(x | y);
			}
			//else if(ss[i] == '!')
			else if(ss[i] == '>')
			{
				if(x == 1 && y == 0) num.push(0);
				else num.push(1);
			}
			else if(ss[i] == '~')
			{
				if(x == y) num.push(1);
				else num.push(0);
			}
		}
	}
	return num.top();
}
void solve()
{
	cout << "请输入变元个数(小于26个)" << endl;
	cin >> n;
	cout << "请依次输入变元(大写字母)" << endl;
	for(int i = 0; i < n; i++) 
	{
		char tmp;
		cin >> tmp;
		v.push_back(tmp);
	}

	cout << "请输入第一个表达式" << endl;
	cin >> s;
	string tmp = "";//首先对原字符串进行处理,把!A换成a,反正!的优先级最高

	for(int i = 0; i < s.size(); i++)
	{
		//cout << i << ' ';
		if(i >= s.size()) break;
		if(s[i] != '!')
		{
			tmp = tmp + s[i]; 
		}
		else
		{
			tmp = tmp + (char)(s[i + 1] - 'A' + 'a');
			i++;
		}
		//cout << i << endl;
	}
	s = tmp;
	ss = "";
	work1();
	//cout << "其后缀表达式为:" << ss << endl;
	for (int i = 0; i < fpow(2, n); i++)
	{
		int ii = i;
		for(int j = n; j >= 1; j--)//构造真值表 倒序利用位运算
		{
			TruthTable1[i][j] = (ii & 1);
			ii >>= 1;
			mp[v[j - 1]] = TruthTable1[i][j];
			mp[v[j - 1] - 'A' + 'a'] = 1 - TruthTable1[i][j];
		}
		
		TruthTable1[i][n + 1] = work2();
	}

	cout << "请输入第二个表达式" << endl;
	cin >> s;
	tmp = "";//首先对原字符串进行处理,把!A换成a,反正!的优先级最高
	for(int i = 0; i < s.size(); i++)
	{
		if(i >= s.size()) break;
		if(s[i] != '!')
		{
			tmp = tmp + s[i]; 
		}
		else
		{
			tmp = tmp + (char)(s[i + 1] - 'A' + 'a');
			i++;
		}
	}
	s = tmp;
	ss = "";
	work1();
	//cout << "其后缀表达式为:" << ss << endl;
	for (int i = 0; i < fpow(2, n); i++)
	{
		int ii = i;
		for(int j = n; j >= 1; j--)//构造真值表 倒序利用位运算
		{
			TruthTable2[i][j] = (ii & 1);
			ii >>= 1;
			mp[v[j - 1]] = TruthTable2[i][j];
			mp[v[j - 1] - 'A' + 'a'] = 1 - TruthTable2[i][j];
		}

		TruthTable2[i][n + 1] = work2();
	}
	bool flag = 1;
	for(int i = 0; i < fpow(2, n); i++)
	{
		if(TruthTable1[i][n + 1] != TruthTable2[i][n + 1])
		{
			flag = 0;
			cout << "两表达式不等值!" << endl;
		}
	}
	if(flag) cout << endl << "两表达式等值!" << endl;
	cout << endl << "第一个表达式的真值表:" << endl;
	for(int i = 0; i < n; i++) cout << v[i] << ' ';
	cout << ' ' << 'F' << endl;
	for(int i = 0; i < fpow(2, n); i++)
	{
		for(int j = 1; j <= n; j++)
		{
			cout << TruthTable1[i][j] << ' ';
		}
		cout << ' ' << TruthTable1[i][n + 1] << endl;
	}
	cout << endl;
	cout << "第二个表达式的真值表:" << endl;
	for(int i = 0; i < n; i++) cout << v[i] << ' ';
	cout << ' ' << 'F' << endl;
	for(int i = 0; i < fpow(2, n); i++)
	{
		for(int j = 1; j <= n; j++)
		{
			cout << TruthTable2[i][j] << ' ';
		}
		cout << ' ' << TruthTable2[i][n + 1] << endl;
	}
}
int main()
{
	freopen("data.txt", "r", stdin);
	init();
	solve();
	return 0;
}
posted @ 2020-10-19 23:26  脂环  阅读(552)  评论(0编辑  收藏  举报