码蹄杯 新的表达式 知识点:模拟 栈

62 阅读3分钟

码题集OJ-新的表达式 (matiji.net) image.png

样例输入:

(1&2|3)&(4|5&6)

样例输出:

3

image.png

思想

1.读入字符串s

2.创建一个 op(操作符)栈 一个st(操作数)栈

3.遍历字符串s

一.如果s[i]是 (,就入 op栈。 如果是) 就将()内的元素进行计算。直到遇到下一个(为止。

二.如果取出来的是 & | 就直接进行计算。

三.如果取出来的是数字字符,就将其组合为一个数字,加入到st栈。

四.计算函数如下

:从st栈 栈顶取出两个操作数

:从op栈 栈顶取出一个操作符

进行计算 。


#include<bits/stdc++.h>
using namespace std;


//判断是否为操作符 & |
bool is_op(char c)
{
	return c == '&' || c == '|';
}
//判断操作符的优先级 因为本题操作符只有& | ,而& |的优先级是一样的
int priority(char op)
{
	if (op == '&' || op == '|')
		return 1;
	return -1;
}

//计算
void process_op(stack<int>& st, char op)
{
	int r = st.top();
	st.pop();
	int l = st.top();
	st.pop();

	switch (op)
	{
	case '&':
		st.push(min(l, r));
		break;
	case '|':
		st.push(max(l, r));
		break;
	}
}
int solve(string s)
{
	stack<int>st;     //操作数
	stack<char>op;   //操作符

	for (int i = 0; i < s.size(); i++)
	{


		       //如果遇见的是(括号 )括号
		if (s[i] == '(')  //如果遇见(就入栈
			op.push(s[i]);
		else if (s[i] == ')')  //遇到),先把()内的处理完
		{
			while (op.top() != '(')
			{
				process_op(st, op.top());  //计算
				op.pop();  //弹出操作符
			}
			op.pop();  //把)也弹出
		}

		     //如果遇见的是 操作符
		else if(is_op(s[i]))  
	    {
			char  cur_op = s[i];  //保存一下当前操作符
			while (!op.empty() && priority(op.top()) >= priority(cur_op) )  //比较一下 操作栈  栈顶操作符 和  当前操作符 谁的优先级大
			{
				process_op(st, op.top());
				op.pop();
			}
			op.push(cur_op);
		}

		   //遇到遇见的是操作数
		     // 假如说是 '1' '2' '3'我们就需要拼接为: 123
		else     
		{
			int number = 0;
			while(i<(int)s.size() && isdigit(s[i]))
			{
				number = number * 10 + s[i++] - '0';
			} 
			i--;
			st.push(number);
		}
	}
    
	//如果操作符栈里还有操作符,那就还需要处理
	while (!op.empty())
	{
		process_op(st,op.top());
		op.pop();
	}
	return st.top();
}

int main()
{
	string s; cin >> s;
	cout<<solve(s);
	return 0;
}#include<bits/stdc++.h>
using namespace std;


//判断是否为操作符 & |
bool is_op(char c)
{
	return c == '&' || c == '|';
}
//判断操作符的优先级 因为本题操作符只有& | ,而& |的优先级是一样的
int priority(char op)
{
	if (op == '&' || op == '|')
		return 1;
	return -1;
}

//计算
void process_op(stack<int>& st, char op)
{
	int r = st.top();
	st.pop();
	int l = st.top();
	st.pop();

	switch (op)
	{
	case '&':
		st.push(min(l, r));
		break;
	case '|':
		st.push(max(l, r));
		break;
	}
}
int solve(string s)
{
	stack<int>st;     //操作数
	stack<char>op;   //操作符

	for (int i = 0; i < s.size(); i++)
	{


		       //如果遇见的是(括号 )括号
		if (s[i] == '(')  //如果遇见(就入栈
			op.push(s[i]);
		else if (s[i] == ')')  //遇到),先把()内的处理完
		{
			while (op.top() != '(')
			{
				process_op(st, op.top());  //计算
				op.pop();  //弹出操作符
			}
			op.pop();  //把)也弹出
		}

		     //如果遇见的是 操作符
		else if(is_op(s[i]))  
	    {
			char  cur_op = s[i];  //保存一下当前操作符
			while (!op.empty() && priority(op.top()) >= priority(cur_op) )  //比较一下 操作栈  栈顶操作符 和  当前操作符 谁的优先级大
			{
				process_op(st, op.top());
				op.pop();
			}
			op.push(cur_op);
		}

		   //遇到遇见的是操作数
		     // 假如说是 '1' '2' '3'我们就需要拼接为: 123
		else     
		{
			int number = 0;
			while(i<(int)s.size() && isdigit(s[i]))
			{
				number = number * 10 + s[i++] - '0';
			} 
			i--;
			st.push(number);
		}
	}
    
	//如果操作符栈里还有操作符,那就还需要处理
	while (!op.empty())
	{
		process_op(st,op.top());
		op.pop();
	}
	return st.top();
}

int main()
{
	string s; cin >> s;
	cout<<solve(s);
	return 0;
}

image.png