逻辑运算优先级:! > & > |
例如:
1|(1&0)=1
1&0|0&1=0
!0&1|0=1
((!0&1))|0=1
思路:用栈来维护数字、运算符和括号。先去括号内的子表达式,然后遍历一遍把!都消掉,然后用栈先把&都消掉,最后计算|运算。
#include<iostream>
#include<string>
#include<sstream>
#include<stack>
#include<algorithm>
using namespace std;
int calc(string s)
{
char c;//符号
int a, b, val;//左操作数、右操作数、计算结果
stack<int> num;//存数字
stack<char> op;//存操作符
//不带括号的表达式中,!优先级最高
for (int i = 0; i < s.length() - 1; i++)
{
if (s[i] == '!')
{
if (s[i + 1] == '1')
{
s[i + 1] = '0';
}
else
{
s[i + 1] = '1';
}
s.erase(s.begin() + i);//把'!'去掉
}
}
//将第一个数字压入数字栈
stringstream ss(s);
ss >> val;
num.push(val);
//每次读取一个符号和数字
while (ss >> c >> val)
{
//如果符号是&,直接与前面的数计算,消去&
if (c == '&')
{
if (1 == val && 1 == num.top())
{
val = 1;
}
else
{
val = 0;
}
num.pop();//弹出已经计算过的数
num.push(val);//压入计算后的结果
}
else//符号是|
{
//将取到的数和符号压栈,op栈中只留|
num.push(val);
op.push(c);
}
}
//操作符栈不为空,只有|运算
while (!op.empty())
{
a = num.top();
num.pop();
b = num.top();
num.pop();
if (0 == a && 0 == b)
{
num.push(0);
}
else
{
num.push(1);
}
op.pop();
}
return num.top();
}
int main()
{
string str;//表达式字符串
getline(cin, str);
stack<int> kuohao;//存括号
int len = str.size();
int from, to;
for (int i = 0; i < len; i++)
{
if (str[i] == '(' || str[i] == ')')
{
//括号不匹配
if (kuohao.empty() || str[i] == str[kuohao.top()])
{
kuohao.push(i);//栈里存放的是'('')'在str中的index
}
else//括号匹配
{
from = kuohao.top();
to = i; //定位到一组()
kuohao.pop();//计算过的出栈
//求解括号中的表达式
int tmp = calc(str.substr(from + 1, to - from - 1));
//把所求结果替换掉括号部分的表达式
stringstream ss;
ss << tmp;
string tmpS;
ss >> tmpS; //int->string
str.replace(str.begin() + from, str.begin() + to + 1, tmpS.begin(), tmpS.end());//'('...')'之间有to-from+1个字符!
len = str.size();//循环条件记得更新
i = from - 1;
}
}
}
int result = calc(str);
cout << result << endl;
return 0;
}
来源:https://blog.csdn.net/zdluffy/article/details/98957766