华为机试题之表达式求值

今天做了华为机试,最后一道题做错了,回来又重新写了一下。

表达式求值往年好像有的,但是这次的题加了括号,所以写起来麻烦了一些。

还有就是在处理+-号的时候做错了,可能是当时脑袋太蒙了,没有看出来,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


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值