zoukankan      html  css  js  c++  java
  • 【模拟 + 栈】AcWing 151. 表达式计算4

    这题括号多余的情况好恶心 orz,以及负数的情况也增加了这题的难度。

    分析

    首先,解决一般的中缀表达式转后缀表达式问题:

    这里的运算符包括 +,-,*,/,^,当然,扩大运算符包含的集合的时候我们也可以类似推广。

    考虑用一个答案栈 res 以及运算符栈 ops 来操作。

    • 遇到数字的时候,将它丢入 res
    • 遇到左括号的时候,将它丢入 ops
    • 遇到右括号的时候,开始对 ops 执行出栈操作直到遇到左括号
    • 遇到运算符的时候,只要 ops 栈顶的运算符优先级高于当前运算符,就一直对 ops 执行出栈操作。

    这样我们就可以将中缀转后缀了。

    下面对后缀表达式求值:
    考虑用一个栈维护,
    遍历后缀表达式,当遇到的时候就丢入栈;否则遇到的是运算符,此时我们将栈顶两个数拿出来用这个运算符进行运算再将结果丢入栈中。

    遍历完后缀表达式后栈只剩一个数,这就是答案。

    至此,原理讲述完毕。

    但这题很毒瘤,会有括号多余的情况以及负数的情况。

    接下来的操作由为本人乱搞得出,如果找到 hack 数据可以发给我 qwq~,但目前我试了许多奇怪的数据都可以过。

    • 对于括号多余的情况,考虑对原序列 s 进行一遍类似于括号匹配的操作:维护两个变量 cntL, cntR,见代码:
    int cntL=0, cntR=0;
    for(auto i: s){
    	if(i=='(') cntL++;
    	else if(i==')' && cntL) cntL--;
    	else if(i==')' && !cntL) cntR++;
    }
    
    • 然后对于负数的情况,例如 -1+3,将 -1 替换为 (0-1)*

    实现

    // Problem: 表达式计算4
    // Contest: AcWing
    // URL: https://www.acwing.com/problem/content/153/
    // Memory Limit: 64 MB
    // Time Limit: 1000 ms
    // 
    // Powered by CP Editor (https://cpeditor.org)
    
    #include<bits/stdc++.h>
    using namespace std;
    
    #define debug(x) cerr << #x << ": " << (x) << endl
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define dwn(i,a,b) for(int i=(a);i>=(b);i--)
    #define pb push_back
    #define all(x) (x).begin(), (x).end()
    
    #define int long long
    
    using pii = pair<int, int>;
    using ll = long long;
    
    inline void read(int &x){
        int s=0; x=1;
        char ch=getchar();
        while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
        while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
        x*=s;
    }
    
    map<char, int> mp;
    
    string c2str(char ch){
    	string s; s+=ch;
    	return s;
    }
    
    vector<string> get(string s){
    	vector<string> res;
    	stack<char> ops;
    	
    	rep(j,0,s.size()-1){
    		char i=s[j];
    		if(isdigit(i)){
    			string num;
    			while(j<s.size() && isdigit(s[j])){
    				num+=s[j];
    				j++;
    			}
    			res.pb(num);
    			j--;
    		}
    		else if(i=='(') ops.push('(');
    		else if(i==')'){
    			while(ops.top()!='('){
    				res.pb(c2str(ops.top()));
    				ops.pop();
    			};
    			ops.pop();
    		}
    		else{
    			while(ops.size() && mp[ops.top()]>=mp[i]){
    				res.pb(c2str(ops.top()));
    				ops.pop();
    			}
    			ops.push(i);
    		}
    	}
    	while(ops.size()) res.pb(c2str(ops.top())), ops.pop();
    	return res;
    }
    
    int to_int(string s){
    	int res=0;
    	for(auto i: s) res=res*10+i-'0';
    	return res;
    }
    
    int getV(int a, int b, string op){
    	if(op=="+") return a+b;
    	if(op=="-") return a-b;
    	if(op=="*") return a*b;
    	if(op=="/") return a/b;
    	if(op=="^"){
    		int res=1;
    		for(; b; b>>=1, a*=a) if(b&1) res=res*a;
    		return res;
    	}
    }
    
    int cal(vector<string> s){
    	stack<int> stk;
    	for(auto i: s){
    		if(!mp.count(i[0])) stk.push(to_int(i));
    		else{
    			int a=stk.top(); stk.pop();
    			int b=stk.top(); stk.pop();
    			stk.push(getV(b, a, i));
    		}
    	}
    	return stk.top();
    }
    
    signed main(){
    	mp['(']=0;
    	mp['+']=mp['-']=1;
    	mp['*']=mp['/']=2;
    	mp['^']=3;
    
    	string str; cin>>str;
    	string s;
    	rep(i,0,str.size()-1){
    		if(i && str[i]=='-' && !isdigit(str[i-1]) || !i && str[i]=='-'){
    			if(i && str[i-1]==')') s+="+(0-1)*";
    			else s+="(0-1)*";
    		}
    		else s+=str[i];
    	}
    	
    	int cntL=0, cntR=0;
    	for(auto i: s){
    		if(i=='(') cntL++;
    		else if(i==')' && cntL) cntL--;
    		else if(i==')' && !cntL) cntR++;
    	}
    	while(cntL--) s+=')';
    	auto tmp=s;
    	s="";
    	while(cntR--) s+='(';
    	s+=tmp; 
    	
    	cout<<cal(get(s))<<endl;
    	
    	return 0;
    }
    
  • 相关阅读:
    研究显示:众多网上零售商未遵循Web优化基本准则
    坚果云开发团队分享高效代码审查经验
    不应忽视的HTML优化
    开源网络分析工具TCP Traffic Analyzer
    Web 2.0应用客户端性能问题十大根源
    W3C宣布成立Web性能工作组
    Google C++规范
    Yahoo推出开源YUI跨浏览器测试工具Yeti
    比较牛的一个字符画
    python调用windows下的应用程序的方法
  • 原文地址:https://www.cnblogs.com/Tenshi/p/15790187.html
Copyright © 2011-2022 走看看