您的位置:首页 > 其它

hdu 3000 A Simple Language (逆波兰式计算四则运算表达式数值)

2014-07-27 18:38 681 查看

A Simple Language

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 459    Accepted Submission(s): 86


[align=left]Problem Description[/align]
Professor X teaches the C Programming language in college, but he finds it's too hard for his students and only a few students can pass the exam. So, he decide to invent a new language to reduce the burden on students.

This new language only support four data type, but the syntax is an strict subset of C. It only support assignment operation, brackets operation , addition , subtration, multiplication and division between variables and numbers. The priority of operations is
the same as C.

In order to void the problem of forgetting the eliminator ";", this new language allow to omit it.

The variable naming rules is the same as C.

Comments is not allowed in this language.

Now Prof.X need to impelment this language, and the variable part is done by himself. Now Prof.X need you, a execllent ACM coder's help: Given a section of this language's code, please calculate it's return value.
 

[align=left]Input[/align]
The input contains many lines, each line is a section of codes written in the language described above, you can assume that all variables have been declared as int and have been set to 0 initially.
 

[align=left]Output[/align]
To each line of input, output an integer indicate the return value of the input line. the semicolon will only appear in the end of line, you can assume that every literal, variable's value and the intermediate results of calculation
would never bigger than a short integer.

Notice: the result may affect by assignment operation, if you don't know the exact return value of some statements such as a=3, you can try run codes such as ' printf("%d",a=3); ' in C, and check the result.
 

[align=left]Sample Input[/align]

a=3
a+b
a=a*(b+2)+c;
a+b
a/4
_hello=2*a;

 

[align=left]Sample Output[/align]

3
3
6
6
1
12

题目意思就是连续输入多行算术表达式,每行都会返回一个运算结果,变量的初始值都为0,每次赋值都会覆盖原先值并保存下来,输出每行运算结果。

刚学完编译原理,见过类似的形式,首先想到的便是用先逆波兰式表示出来然后再进行运算。就相当于先去掉括号和优先级的约束,当然没有这个约束计算就很简单了,然而事实却并不是那么简单,首先就是负数问题比如a=-b,-1+-2,这种类型,这就要求词法要写好,哪个地方作为分隔符要仔细判断,然后赋值运算的问题,可能出现连续而且带括号的形式,比如a=b= (a=b=1)+1,这种情况下其实只要确定好每个运算符的优先级,把赋值当一般的运算符进行运算就行了。。这两种过了基本就可以ac了。

而且这种题写过一次以后都可以重复用了,写好模板很重要!

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <vector>
#include <map>
#include <cstdlib>
using namespace std;

map<string,int> mp;
////////////////
//RPN reverse Polish notation
class RPN{
private:
string ori;
vector<string> vec;
vector<string> res;
map<string,int> pri;
public:
void initial()
{
vec.clear();
res.clear();
ori = "";
pri["#"] = 0;
pri["="] = 1;
pri["+"] = pri["-"] = 2;
pri["/"] = pri["*"] = 3;
}
void input(string s){
ori = s;
}
void CiFa()
{
string tmp = "";
for(int i=0;i<ori.length();i++)
{
if(ori[i]==' ') continue;
if(i==ori.length()-1 || ori[i+1]=='+' || ori[i+1]=='-' || ori[i+1]=='/' || ori[i+1]=='*' || ori[i+1]=='(' || ori[i+1]==')' || ori[i+1]==' ' || ori[i+1]=='=')
{
tmp += ori[i];
vec.push_back(tmp);
tmp = "";
}
else if(ori[i]=='(' || ori[i]==')' ||ori[i]=='*' || ori[i]=='/' ||ori[i]=='+'||ori[i]=='=')
{
tmp = "";
tmp += ori[i];
vec.push_back(tmp);
tmp = "";
}
else if(ori[i]=='-')
{
if(vec.size()==0 || vec[vec.size()-1]=="(" || vec[vec.size()-1]=="+" || vec[vec.size()-1]=="-" || vec[vec.size()-1]=="*" || vec[vec.size()-1]=="/")
{
tmp+=ori[i];
}
else
{
tmp = "";
tmp += ori[i];
vec.push_back(tmp);
tmp = "";
}
}
else tmp += ori[i];
}
/*
for(int i=0;i<vec.size() ;i++)
{
cout << vec[i] << " ";
}
cout << endl;
*/
}
void process()
{
CiFa();
stack<string> s1;
stack<string> s2;
s1.push("#");
vec.push_back("#");
for(int i=0;i<vec.size();i++)
{
string tmp = vec[i];
if(tmp=="=")
{
string t1 = s1.top();
if(t1=="(" || pri[tmp]>=pri[t1])
{
s1.push(tmp);
}
else{
while(t1!="(" && pri[t1] > pri[tmp] )
{
s2.push(t1);
s1.pop();
t1 = s1.top();
}
s1.push(tmp);
}
}
else if(tmp=="+" || tmp=="-" ||tmp=="*"||tmp=="/")
{
string t1 = s1.top();
if(t1=="(" || pri[tmp]>pri[t1])
{
s1.push(tmp);
}
else{
while(t1!="(" && pri[t1] >= pri[tmp] )
{
s2.push(t1);
s1.pop();
t1 = s1.top();
}
s1.push(tmp);
}
}
else if(tmp=="(")
{
s1.push(tmp);
}
else if(tmp==")")
{
string t1 = s1.top();
while(t1!="(")
{
s2.push(t1);
s1.pop();
t1 = s1.top();
}
s1.pop();
}
else if(tmp=="#")
{
string t1 = s1.top();
while(t1!="#")
{
s2.push(t1);
s1.pop();
t1 = s1.top();
}
}
else s2.push(tmp); // num || var
}
// rpn save to stack s2
while(!s2.empty())
{
string tmp = s2.top();
res.insert(res.begin(),tmp);
s2.pop();
}
}
// rpn string
string getRes()
{
string s = "";
for(int i=0;i<res.size();i++)
{
s += res[i];
}
return s;
}
// int to string
string itoa(int x)
{
if(x==0) return "0";
string t = "";
if(x<0)
{
t = "-";
x=-x;
}
char p[50];
int cnt = 0;
while(x>0)
{
p[cnt++] = x%10 + '0';
x /= 10;
}
while(cnt--)
{
t+= p[cnt];
}
return t;
}
int getValue()
{
stack<string> sta;
string str;
int s1,s2;
for(int i=0;i<res.size();i++)
{
if(res[i]=="=")
{
string str1 = sta.top();
sta.pop();
string str2 = sta.top();
sta.pop();
if(str1[0]=='-')
{
if((str1[1]>='0' && str1[1]<='9'))
{
mp[str2] = atoi(str1.c_str());
}
else
{
str1.erase(0);
mp[str2] = -mp[str1];
}
}
else if((str1[0]>='0' && str1[0]<='9'))
{
mp[str2] = atoi(str1.c_str());
}else mp[str2] = mp[str1];

sta.push(str1);
}
else if(res[i]=="+" || res[i]=="-" || res[i]=="*" || res[i]=="/")
{
str = sta.top();
if(str[0]=='-')
{
if((str[1]>='0' && str[1]<='9'))
{
s1 = atoi(str.c_str());
}
else
{
str.erase(0,1);
s1 = -mp[str];
}
}
else if((str[0]>='0' && str[0]<='9') || str[0]=='-') s1 = atoi(str.c_str());
else s1 = mp[str];
sta.pop();
str = sta.top();
if(str[0]=='-')
{
if((str[1]>='0' && str[1]<='9'))
{
s2 = atoi(str.c_str());
}
else
{
str.erase(0,1);
s2 = -mp[str];
}
}
else if((str[0]>='0' && str[0]<='9') || str[0]=='-') s2 = atoi(str.c_str());
else s2 = mp[str];
sta.pop();
int tmp = 0;

if(res[i]=="+") tmp = s2 +s1;
if(res[i]=="-") tmp = s2 -s1;
if(res[i]=="*") tmp = s2 *s1;
if(res[i]=="/") {
if(s1!=0) tmp = s2 /s1;
else tmp = 0;
}

// char buffer[100];
// cout << "tmp:" << tmp << endl;
//itoa(tmp,buffer);
sta.push(itoa(tmp));
}
else{
sta.push(res[i]);
}
}
str = sta.top();
if((str[0]>='0' && str[0]<='9') || str[0]=='-') return atoi(str.c_str());
return mp[str];
}
};
//////////////////////
int solve(string s)
{
RPN rpn;
rpn.initial();
rpn.input(s);
rpn.process();
// cout << rpn.getRes() <<endl;
return rpn.getValue();
}
int main()
{
string s;
while(getline(cin,s))
{
int len = s.length();
if(s[len-1]==';') s.erase(len-1);
cout << solve(s) << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: