后缀表达式计算器代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 

class Expression
{
public:
	enum OpType
	{
		NoType,
		Operator,    // '+', '-', '*', '/'等
		Operand,     // 数字
		BeginSymbol, // '('
		EndSymbol,   // ')'
	};
	struct OpData
	{
		double value;
		OpType type;
	};

	typedef std::vector PrefixType;

	Expression()
	{
		m_priority.insert(std::make_pair('+', 0));
		m_priority.insert(std::make_pair('-', 0));
		m_priority.insert(std::make_pair('*', 1));
		m_priority.insert(std::make_pair('/', 1));
	}

	bool IsOperator(int v) const
	{
		return m_priority.find(v) != m_priority.end();
	}

	bool IsOperand(int v) const
	{
		return v >= '0' && v <= '9' || v == '.';
	}

	bool IsEndSymbol(int v) const
	{
		return v == ')';
	}

	bool IsBeginSymbol(int v) const
	{
		return v == '(';
	}

	int GetPriority(int v) const
	{
		std::map::const_iterator itr = m_priority.find(v);
		if (itr != m_priority.end())
		{
			return itr->second;
		}
		return -1;
	}

	double GetResult(double a, double b, int op)
	{
		double r = 0;
		switch (op)
		{
		case '+':
			r = a + b;
			break;
		case '-':
			r = a - b;
			break;
		case '*':
			r = a * b;
			break;
		case '/':
			assert(b != 0);

			r = a / (double)b;
			break;
		default:
			break;
		}
		return r;
	}

	//中缀表达式 转为 前缀表达式
	int ToPrefix(const std::string &src, PrefixType &dest)
	{
		if (src.empty())
		{
			return -1;
		}
		std::stack s1;
		std::stack s2;
		std::string num;
		for (std::string::const_reverse_iterator itr = src.rbegin(); itr != src.rend(); ++itr)
		{
			const int v = *itr;
			if (IsOperand(v))
			{
				num.push_back(v);
			}
			else
			{
				if(!num.empty())
				{
					std::reverse(num.begin(), num.end());
					s2.push(OpData{ atof(num.c_str()), Operand });
					num.clear();
				}
				
				if (IsOperator(v))
				{
					while (1)
					{
						if (s1.empty())
						{
							s1.push(OpData{ (double)v, Operator });
							break;
						}

						const OpData topV = s1.top();
						if (topV.type == EndSymbol || (topV.type == Operator && GetPriority(v) >= GetPriority(topV.value)) )
						{
							s1.push(OpData{ (double)v, Operator });
							break;
						}

						s2.push(topV);
						s1.pop();
					}
				}
				else if (IsEndSymbol(v))
				{
					s1.push(OpData{ (double)v, EndSymbol });
				}
				else if (IsBeginSymbol(v))
				{
					while (!s1.empty())
					{
						const OpData topV = s1.top();
						s1.pop();
						if (topV.type == EndSymbol)
						{
							break;
						}
						s2.push(topV);
					}
				}
			}
		}
		if (!num.empty())
		{
			std::reverse(num.begin(), num.end());
			s2.push(OpData{ atof(num.c_str()), Operand });
			num.clear();
		}

		while (!s1.empty())
		{
			s2.push(s1.top());
			s1.pop();
		}
		while (!s2.empty())
		{
			dest.push_back(s2.top());
			s2.pop();
		}

		return 0;
	}

	//int ToPostfix(const std::string &src, std::string &dest) {}

	//计算前缀表达式的结果
	int CalculatePrefix(const PrefixType & prefix, double &result)
	{
		std::stack s;
		for (PrefixType::const_reverse_iterator itr = prefix.rbegin(); itr != prefix.rend(); ++itr)
		{
			const OpData v = *itr;
			if (v.type == Operand)
			{
				s.push(v.value);
			}
			else if (v.type == Operator)
			{
				if (s.size() < 2)
				{
					return -2;
				}
				double a = s.top();
				s.pop();
				double b = s.top();
				s.pop();

				double c = GetResult(a, b , v.value);
				//std::cout << a << " " << (char)v.value << " " << b << " = " << c << std::endl;
				s.push(c);
			}

		}
		if (s.size() != 1)
		{
			return - 1;
		}

		result = s.top();

		return 0;
	}

	friend inline std::ostream &operator<<(std::ostream &stream, const Expression::OpData &v)
	{
		if (v.type == Expression::Operand)
			stream << v.value;
		else
			stream << (char)v.value;
		return stream;
	}

	static std::string ToStr(const Expression::PrefixType &result)
	{
		std::stringstream ss;
		for (Expression::PrefixType::const_iterator itr = result.begin(); itr != result.end(); ++itr)
		{
			ss << " " << *itr;
		}
		return ss.str();
	}

private:
	std::map m_priority;
};

int main(int argc, char **argv)
{
	std::string src = argc > 1 ? argv[1] : "12+((2+73)*4)-15";
	std::cout << "src: " << src << std::endl;
	Expression expression;

	Expression::PrefixType result;
	
	int ret = expression.ToPrefix(src, result);
	if (ret != 0)
	{
		std::cout << src << " ToPrefix Error." << std::endl;
		return 1;
	}

	std::cout << "prefix: " << Expression::ToStr(result) << std::endl;

	double opResult = 0;
	ret = expression.CalculatePrefix(result, opResult);
	if (ret != 0)
	{
		std::cout << Expression::ToStr(result) << " Calculate Error." << std::endl;
		return 2;
	}

	std::cout << "calculate: " << opResult << std::endl;
	if (argc == 1)
	{
		assert((int)opResult == 297);
	}

	getchar();
	return 0;
}

你可能感兴趣的:(C++)