去除冗余括号

                要求:如:(a*b)+c/d应输入(*)+/

                                输出*+/

                a+b/(c-d)应输入+/(-)

                                输出+/(-)

                a+(b+c)应输入+(+)

                                输出++

        看到括号我们首先想到用栈解决,且应想到符号的优先级,即“ * ”,“ / ” >  " + ", " - "

        由于去除括号的情况需要同时考虑左括号左边符号,右括号右边符号对括号内部的影响,较麻烦,故直接考虑括不去除括号情况,即:左括号左侧为“ - ”或“ * ”且括号内部存在+-不可去括号, 左括号左侧符号“ / ”不可去括号,* ( ):括号右侧为“ * ”或“ / ”且括号内存在+-不可去括号

#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII; 

stack<int> sta;
vector<PII> v;
string s;
map<char, int> signlevel;

sta,用于存储左括号的位置, v,用于存储括号的配对信息。 signlevel,用于存储不同符号的优先级。

bool check(int a, int b) { 
	stack<int> tmp;  
	vector<char> sign;
	char leftsign = s[a-1], rightsign = s[b+1];
	int mnlv = 3; 
	int rslv = signlevel[rightsign];  
	

tmp临时栈,用于判断是否处于内部括号范围内。sign,用于存储括号内的符号。char leftsign = s[a-1], rightsign = s[b+1]获取括号左边的符号和右边的符号。mnlv = 3表示括号内符号优先级最低的初始值。rslv获取右边符号的优先级。

for(int i = a+1;i <= b-1;i ++) { 
		if(s[i] == ' ') continue;
		if(tmp.empty()) { 
			if(s[i] == '(') tmp.push(1); 
			else if(!isalpha(s[i])) sign.push_back(s[i]); 
		} else if(s[i] == ')') tmp.pop(); 
	}
	
	for(int i = 0;i < sign.size();i ++) 
	mnlv = min(mnlv, signlevel[sign[i]]);  

循环遍历sign向量,找到括号内符号的最低优先级

	if(mnlv < rslv) return false; 
	if(((leftsign == '-' || leftsign == '*') && mnlv != 2) || leftsign == '/')
	return false;
	return true; 
}

如果括号内符号的最低优先级小于右边符号的优先级,或者左边符号是-*且括号内符号最低优先级不是 2,或者左边符号是/,则返回false;否则返回true

int main()
{

	signlevel[' '] = 0; signlevel['('] = 0; signlevel[')'] = 0;
	signlevel['+'] = 1; signlevel['-'] = 1; signlevel['*'] = 2; signlevel['/'] = 2; 

初始化符号优先级。空格、左括号和右括号的优先级为 0,加号和减号的优先级为 1,乘号和除号的优先级为 2。

	while(cin>>s) {
		v.clear(); 
		int n = s.size();
		s = ' '+s+' '; 
		for(int i = 1;i <= n;i ++) 
		if(s[i] == '(') sta.push(i); 
		else if(s[i] == ')') v.push_back(PII(i, sta.top())), sta.pop();  
		sort(v.begin(), v.end()); 
		for(int i = 0;i < v.size();i ++) {
			int a = v[i].second, b = v[i].first;
			if(check(a, b)) s[a] = s[b] = ' '; 
		}
		
		for(int i = 1;i <= n;i ++) if(s[i] != ' ') cout << s[i]; puts("");
	}
}

遍历,调用check函数判断是否可以去括号,如果可以,则将括号对应的字符设置为空格。遍历字符串,输出非空格字符,即去除括号后的表达式。

o(*▽*)q

多多支持呀╰(*°▽°*)╯

收起

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值