函数实现复合命题的计算及判断两个命题是否等值——中缀表达式转后缀表达式
主要是中缀转后缀+构造真值表进行判断,借助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;
}