华为OJ—四则运算
2016-08-10 16:49
204 查看
题目如下:
描述:请实现如下接口
/* 功能:四则运算
* 输入:strExpression:字符串格式的算术表达式,如: "3+2*{1+2*[-4/(8-6)+7]}"
* 返回:算术表达式的计算结果
*/
public static int calculate(String strExpression)
{
/* 请实现*/
return 0;
}
约束:
pucExpression字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。
pucExpression算术表达式的有效性由调用者保证;
知识点 栈
运行时间限制 10M
内存限制 128
输入
输入一个算术表达式
输出
得到计算结果
样例输入 3+2*{1+2*[-4/(8-6)+7]}
样例输出 25
解答要点:
1、需要将中缀表达式转换为后缀表达式后,然后按顺序进行计算;2、需要注意数值可能出现负数。
代码
#include<string> #include<stack> #include<vector> #include<iostream> #include<sstream> using namespace std; // 四则运算, //获得优先级 int getPriorty(char &c) { switch(c) { case '{': case '[': case '(': return -1; case '+': case '-': return 0; case '*': case '/': return 1; case '}': return 2; case ']': return 3; case ')': return 4; } } //元素类,表示表达式中的一个元素(数值或者运算符),因为可能存在负数,故此处需要进行封装 typedef struct ELEMENT { unsigned _type; //元素类型,0表示元素,1表示运算符,-1表示无效 int _value; //数值 char _c_operation; //运算符 int _priority; //运算符优先级 ELEMENT() { _type=-1; }; ELEMENT(int value) { _type=0; _value=value; }; ELEMENT(char c) { _type=1; _c_operation=c; } //打印输出 static void print(vector<ELEMENT> datas) { for(size_t i=0; i<datas.size(); i++) { if(datas[i]._type==-1) continue; else if(datas[i]._type==0) { if(datas[i]._value<0) cout<<"("<<datas[i]._value<<")"; else cout<<datas[i]._value; continue; } else if(datas[i]._type==1) { cout<<datas[i]._c_operation; continue; } } cout<<endl; } //将结构转化为字符串 static void elements2string(vector<ELEMENT> &datas,string &strResult) { ostringstream out; for(size_t i=0; i<datas.size(); i++) { if(datas[i]._type==-1) continue; else if(datas[i]._type==0) { if(datas[i]._value<0) out<<"("<<datas[i]._value<<")"; else out<<datas[i]._value; continue; } else if(datas[i]._type==1) { out<<datas[i]._c_operation; continue; } } strResult=out.str(); } } Element; //string 转int inline int string2int(string &str) { istringstream sitemp(str); int temp; sitemp>>temp; return temp; } //中缀表达式转后缀表达式 //读入表达式,如果是数字则入队(element) //如果是运算符,比较运算符与栈顶运算符的优先级,如果栈顶运算符的优先级大于等于当前运算符,则将栈顶运算符出栈入队直到栈顶运算符优先级小于等于 // 当前运算符为止,然后将当前运算符入栈;否则当前运算符直接入栈 // “{}”“()”的优先级是最高的,“{”或“(”只有在遇到“}”“)”才出栈 void infix2postfixEx(string &strInFix, vector<Element> &elements) { stack<char> stOperation; //运算符栈 for(size_t i=0; i<strInFix.length(); i++) { char c=strInFix[i]; if(c<'0'||c>'9')//如果是运算符 { if(c=='-')//如果运算符是'-',其有可能是负号标志,也有可能是减号 { if(i==0|| strInFix[i-1]=='{'||strInFix[i-1]=='['||strInFix[i-1]=='('||strInFix[i-1]=='*'||strInFix[i-1]=='/'|| strInFix[i-1]=='+'||strInFix[i-1]=='-') //如果'-'是第一位或者'-'前面是*,/,{,[,(,+,- 。说明该'-'表示的是负号;否则表示正常的运算符 { string str=string(1,c)+strInFix[++i]; int temp=string2int(str); elements.push_back(Element(temp)); continue; } } if(stOperation.empty()) stOperation.push(c); else { if(c=='{'||c=='['||c=='(') { stOperation.push(c); continue; } else if(c==')') { while(stOperation.top()!='(') { elements.push_back(Element(stOperation.top())); stOperation.pop(); } stOperation.pop(); continue; } else if(c=='}') { while(stOperation.top()!='{') { elements.push_back(Element(stOperation.top())); stOperation.pop(); } stOperation.pop(); continue; } else if(c==']') { while(stOperation.top()!='[') { elements.push_back(Element(stOperation.top())); stOperation.pop(); } stOperation.pop(); //弹出'[' continue; } if(getPriorty(stOperation.top())<getPriorty(c)) //栈顶运算符优先级小于当前运算符,则将当前运算符入栈 stOperation.push(c); else//栈顶运算符优先级大于等于当前运算符,则将栈顶运算符出栈入队,直到栈顶运算符优先级小于当前运算符为止 { while(!stOperation.empty()&&getPriorty(stOperation.top())>=getPriorty(c)) { elements.push_back(Element(stOperation.top())); stOperation.pop(); } stOperation.push(c); } } } else //如果是数字,则直接入队 { string str=string(1,c); int temp=string2int(str); elements.push_back(Element(temp)); } } while(!stOperation.empty()) { elements.push_back(Element(stOperation.top())); stOperation.pop(); } //Element::print(elements); } void calculate(string &strInFix,string &strOutResult){ vector<Element> elements;//后缀表达式 infix2postfixEx(strInFix,elements); //根据后缀表达式进行计算 stack<int> datas; for(auto &t:elements){ if(t._type==0) datas.push(t._value); else if(t._type==1){ auto t1=datas.top(); datas.pop(); auto t2=datas.top(); datas.pop(); if(t._c_operation=='+') datas.push(t2+t1); else if(t._c_operation=='-') datas.push(t2-t1); else if(t._c_operation=='*') datas.push(t2*t1); else if(t._c_operation='/') datas.push(t2/t1); } } ostringstream out; out<<datas.top(); strOutResult=out.str(); } int main() { string str,strPostFix; getline(cin,str); calculate(str,strPostFix); cout<<strPostFix; }