Brackets Removal UVA - 1662

感觉这道题目并不是在考察图论相关的算法。首先是读入相应的括号对的信息,包括这对括号的开始位置、结束位置以及对应的长度,然后按照括号对的长度以及开始位置进行排序,然后逐个取出括号对来进行判断。首先判断对应的括号外面的符号,如果是乘除号,那么就判断对应的括号内部是否存在加减号,如果存在加减号,那么说明对应的括号是不能够删除的,并且内部的符号都是不能改变的,如果不存在加减号,那么括号可以删除,并且内部的符号都反转。如果括号的外部是加号,那么就可以直接删除括号,其他的保持不变;如果外部是减号,那么可以删除外部的括号,同时内部的加减号要进行反转,如果外部是乘号,同时内部没有加减号,那么括号可以直接进行删除;如果外部是除号,同时内部不存在加减号,那么外围的括号可以删除,同时内部的乘除号要进行反转。这里使用了一个数组visit,如果元素为0,代表的是符号可以改变,如果为-1,说明符号不能改变,如果为1,说明符号直接删除,最后输出那些剩余的符号即可,具体实现见如下代码:

#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;

char data[1005];

class section{
public:
	int start, end, length;
};

bool compare(const section a,const section b){
	if (a.length != b.length) return a.length < b.length;
	return a.start < b.start;
}

class Solve{
public:
	
	int judge(int ind){
		if (data[ind] == '+') return 1;
		else if (data[ind] == '-') return 2;
		else if (data[ind] == '*') return 3;
		else if (data[ind] == '/') return 4;
		return -1;
	}

	void Deal(){
		vector<section> Section;
		int L = strlen(data+1);
		stack<int> st;
		for (int i = 1; i <= L; i++){
			if (data[i] == '(') st.push(i);
			if (data[i] == ')'){
				int x = st.top();
				st.pop();
				section temp;
				temp.start = x;
				temp.end = i;
				temp.length = i - x + 1;
				Section.push_back(temp);
			}
		}
		sort(Section.begin(), Section.end(), compare);
		int visit[1005];
		memset(visit,0,sizeof(visit));//0代表可以变化
		for (int i = 0; i < Section.size(); i++){
			int l_flag = judge(Section[i].start - 1);
			int r_flag = judge(Section[i].end + 1);
			bool flag = true;
			if (l_flag == 3 || l_flag == 4 || r_flag == 3 || r_flag == 4){//如果外部是乘除 内部不要有加减
				for (int j = Section[i].start + 1; j < Section[i].end; j++){
					if (visit[j] == -1) continue;//-1代表不可变化
					if (data[j] == '+' || data[j] == '-'){
						flag = false;//这个时候连同外面的符号都是不能删除的
						break;
					}
				}
				if (!flag){
					for (int j = Section[i].start; j <= Section[i].end; j++)
						if (visit[j]==0) visit[j] = -1;
				}
			}
			if ((l_flag == 1 || l_flag == -1)&&flag){//如果外面的是加号 或者是没有符号
				visit[Section[i].start] = 1;
				visit[Section[i].end] = 1;
			}
			if (l_flag == 2&&flag){//如果外面的是减号 那么就将可以保留下来的加减号进行反转
				visit[Section[i].start] = 1;
				visit[Section[i].end] = 1;
				for (int j = Section[i].start + 1; j < Section[i].end; j++){
					if (visit[j] !=-1 && data[j] == '+') data[j] = '-';
					else if (visit[j] !=-1 && data[j] == '-') data[j] = '+';
				}
			}

			if (l_flag == 3 && flag){//处理对应的乘号 也就是直接去括号
				visit[Section[i].start] = 1;
				visit[Section[i].end] = 1;
			}
			
			if (l_flag == 4 && flag){//处理对应的除号
				visit[Section[i].start] = 1;
				visit[Section[i].end] = 1;
				for (int j = Section[i].start ; j <= Section[i].end; j++){
					if (visit[j] !=-1 && data[j] == '/') data[j] = '*';
					else if (visit[j] !=-1 && data[j] == '*') data[j] = '/';
				}
			}
		}
		for (int i = 1; i <= L; i++){
			if (visit[i] != 1) cout << data[i];
		}
		cout << endl;
	}
};

int main(){
	Solve a;
	string s;
	while (cin>>s){
		memset(data,0,sizeof(data));
		for (int i = 0; i < s.size(); i++) data[i + 1] = s[i];
		a.Deal();
	}
	return 0;
}

//x/(y+z)/(a*(b-c)/d/(e/f))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值