题目如下:
描述:
请实现如下接口
/* 功能:四则运算
* 输入: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;
}