zoukankan      html  css  js  c++  java
  • 函数实现复合命题的计算及判断两个命题是否等值——中缀表达式转后缀表达式

    主要是中缀转后缀+构造真值表进行判断,借助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;
    }
    
  • 相关阅读:
    eNSP——配置Trunk接口
    eNSP——VLAN基础配置和Access
    C# WinForm多线程(三)---- Control.Invoke[转]
    C# 在字符串前加了$,这个 dollar 符号有什么用?美元符号是什么意思
    软件工程领域工程硕士培养方案
    C#中SHOWDIALOG()与SHOW()的区别_模态与非模态_销毁与释放
    HTTP状态代码code(错误代码集合)返回错误代码集合
    OpenCV26HoughCircles 霍夫圆变换原理及圆检测
    OpenCV25-判断一个点是否在多边形的内部_点多边形测试pointPolygonTest
    OpenCV24霍夫直线变换API介绍_3.1.0
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/13843945.html
Copyright © 2011-2022 走看看