您的位置:首页 > 理论基础 > 数据结构算法

华为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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息