今天做了华为机试,最后一道题做错了,回来又重新写了一下。
表达式求值往年好像有的,但是这次的题加了括号,所以写起来麻烦了一些。
还有就是在处理+-号的时候做错了,可能是当时脑袋太蒙了,没有看出来,160的题只得了61分(不过话说这个1是咋来的?)。
下面附上代码吧:
#ifndef _RESULT_OF_EXPRESS_H_
#define _RESULT_OF_EXPRESS_H_
#include <string>
#include <list>
int calculate_single(int left, int right, char op)
{
switch (op)
{
case '+':
return left+right;
case '-':
return left-right;
case '*':
return left*right;
case '/':
return left/right;
default:
break;
}
return 0;
}
int toi(const string& exp, size_t left, size_t right)
{
int ret = 0;
for (; left < right; ++left)
{//
ret = ret*10 + (exp[left]-'0');
}
return ret;
}
//基本思路就是看当前处理的符号,如果是+-号的话,那么要先求前一个值
//比如1+2-4,那么处理-号的时候,要把1+2先计算出来,因为1+2肯定是在-号之前处理的
//对于*/的话,只有当它的前一个op是*或者/的时候才能计算
//这个实际上是为了消除*/
//对于(来说,就是找到下一个),注意题目要求是没有嵌套括号的。然后再calculate。
int calculate(const string& exp, size_t left, size_t right)
{
list<int> operants;
list<int> operators;
size_t p, q;
int dig;
for (p = left, q = left; p < right; ++p)
{//
if (exp[p] >= '0' && exp[left] <= '9')
{//
continue;
}
char op = exp[p];
if (op == '(' || op == ')')
{//
if (op == ')')
{//error
;
}
size_t pos;
for (pos = p+1; pos < right; pos++)
{//
if (exp[pos] == ')')
{//
break;
}
}
dig = calculate(exp, p+1, pos);
p = pos;
q = p+1;
if (p+1 == right)
{//处理完了
operants.push_back(dig);
continue;
}
else
{
p++;
op = exp[p];
}
}
else
{
dig = toi(exp, q, p);
}
bool need_cal = false;
if (op == '+' || op == '-')
{//
if (!operators.empty())
{//
need_cal = true;
}
}
else if (op == '*' || op == '/')
{//
if (!operators.empty() && (operators.back() == '*' || operators.back() == '/'))
{//
need_cal = true;
}
}
else
{//error
;
}
//
if (need_cal)
{//
int a = operants.back();
operants.pop_back();
char o = operators.back();
operators.pop_back();
operants.push_back(calculate_single(a, dig, o));
}
else
{
operants.push_back(dig);
}
operators.push_back(op);
q = p+1;
}
if (p != q)
{//
operants.push_back(toi(exp, q, p));
}
//最后只剩加减法了
while (!operators.empty())
{//
int a = operants.front();
operants.pop_front();
int b = operants.front();
operants.pop_front();
char o = operators.front();
operators.pop_front();
operants.push_back(calculate_single(a, b, o));
}
return operants.front();
}
#endif