华为笔试题:带括号的逻辑运算

我是研究僧i 提交于 2019-11-26 16:44:55

逻辑运算优先级:! > & > |

例如:

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;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!