To my CSDN

C++ | 栈的应用(逆波兰算法) | 计算器

#include <iostream>

using std::cin;
using std::cout;
using std::endl;

template<typename T>
class Stack
{
public:
	Stack(int _size = 20) :size(_size), mtop(0)
	{
		data = new T[size]();
	}
	~Stack()
	{
		delete[] data;
	}
	/* 判空 */
	bool empty()
	{
		return mtop == 0;
	}
	void push(int val)
	{
		if (Full())
		{
			throw std::exception("error: Stack is Full !");
		}
		data[mtop] = val;
		mtop++;
	}
	T top()
	{
		if (empty())
		{
			throw std::exception("error: The stack is empty !");
		}
		return data[mtop - 1];
	}
	void pop()
	{
		if (empty())
		{
			throw std::exception("error: Stack is Empty !");
		}
		mtop--;
	}
	void show()
	{
		if (empty())
		{
			cout << endl;
		}
		else
		{
			int i = 0;
			while (i < mtop)
			{
				cout << data[i] << " ";
				i++;
			}
			cout << endl;
		}
	}
private:
	bool Full()
	{
		return mtop == size;
	}
	T* data;
	int mtop;
	int size;
};



/* 计算器类 */
class Calculator
{
public:
	Calculator(int _size = 20):size(_size),result(0)
	{
		str = new char[_size + 1]();
	}
	~Calculator()
	{
		delete[] str;
	}
	/* 输入 */
	void setData()
	{
		cin.getline(str, size - 1); 		//最多输入size -1个,末尾加'/0'
	}
	/* 中缀转后缀 */
	void InfixToSuffix();		/* 把str输入的中缀式转换为后缀式 */
	/* 后缀计算 */
	void Compure();
	/* 计算结果 */
	double GetResult()
	{
		return result;
	}
private:
	bool IsPop(char a, char b);
	char* str;
	double result;
	int size;

};


int main()
{
	while (1) {
		Calculator ca;
		ca.setData();
		ca.InfixToSuffix();
		ca.Compure();
		cout << ca.GetResult() << endl;

	}
	return 0;
}




bool Calculator::IsPop(char a, char b)	//a为待比较符号,b为符号栈栈顶元素
{
	if (b == '(') return false;
	if (a == '*' || a == '/')
	{
		if (b == '+' || b == '-')
		{
			//可以如符号栈
			return false;
		}
		else
		{
			return true;
		}
	}
	//if (a == '+' || a == '-')
	//{
		//a符号为最低优先级,符号栈出栈
	return true;
	//}
}


/* 中缀转后缀 入栈 */
void Calculator::InfixToSuffix()
{
	char* des = new char[size]();
	/* 符号栈 */
	Stack<char> symbol;

	int i = 0;
	int k = 0;
	while (str[i] != '\0')
	{
		/*----------- 特殊符号判断------------------------------*/
		if (str[i] == ' ')		//如果当前字符是空格,则往后走一个
		{
			i++;
			continue;
		}
		else if (str[i] == '(')	//左括号直接入栈
		{
			symbol.push(str[i]);
		}
		else if (str[i] == ')')	//遇到 ) ,输出( )之间的所有符号
		{
			while (symbol.top() != '(')
			{
				des[k++] = symbol.top();
				des[k++] = ' ';
				symbol.pop();
			}
			symbol.pop();
		}
		/*----------------- 数字 -------------------------------*/
		else if (isdigit(str[i]))
		{
			des[k++] = str[i];
			if (!isdigit(str[i + 1]))		//数字后加空格
			{
				des[k++] = ' ';
			}
		}
		/*----------------- 运算符 -------------------------------*/
		else
		{
			switch (str[i])	
			{
			case '+':case '-':case '*':case '/':
				if (symbol.empty())		//如果符号栈为空,直接入符号
				{
					symbol.push(str[i]);
				}
				else				//否则,判断是否选择入符号栈还是出栈顶元素
				{
					if (IsPop(str[i], symbol.top()))	//出符号栈
					{
						des[k++] = symbol.top();
						symbol.pop();
						continue;
					}
					else			//当前符号优先级高,入符号栈
					{
						symbol.push(str[i]);
					}
				}
				break;
			default:
				break;
			}

		}

		i++;	/* 遍历下一字符 */
	}
	/*字符串已遍历完,把符号栈中剩余的符号入栈到数字栈中 */
	while (!symbol.empty())
	{
		des[k++] = symbol.top();
		symbol.pop();
	}
	des[k] = '\0';

	char* tmp = des;
	des = str;
	str = tmp;
	delete[]des;
}

void Calculator::Compure()
{
	/* 辅助栈 */
	Stack<double> st;

	int i = 0;
	while (str[i] != '\0')
	{
		/*----------- 特殊符号判断------------------------------*/
		if (str[i] == ' ')		//如果当前字符是空格,则往后走一个
		{
			i++;
			continue;
		}

		/*----------------- 数字 -------------------------------*/
		else if (isdigit(str[i]))
		{
			double tmp = 0;
			while (str[i] != ' ')
			{
				tmp = tmp * 10 + str[i] - '0';
				i++;
			}
			st.push(tmp);
		}
		/*----------------- 运算符 -------------------------------*/
		else if (!st.empty())		//非空
		{
			double tmp = 0;
			switch (str[i])
			{
			case '+':
				tmp += st.top();
				st.pop();
				tmp += st.top();
				st.pop();
				st.push(tmp);
				break;
			case '-':
				tmp -= st.top();
				st.pop();
				tmp += st.top();
				st.pop();
				st.push(tmp);
				break;
			case '*':
				tmp = st.top();
				st.pop();
				tmp *= st.top();
				st.pop();
				st.push(tmp);
				break;
			case '/':
			{
				tmp = st.top();
				st.pop();
				if (tmp != 0)
				{
					tmp = st.top() / tmp;
					st.pop();
					st.push(tmp);
				}
				else
				{
					throw std::exception("error: Divisor of 0 !");
				}
			}
			break;
			default:
				break;
			}

		}

		i++;	/* 遍历下一字符 */
	}

	this->result = st.top();
	st.top();
}

运行截图:
在这里插入图片描述

posted @ 2019-11-30 20:49  我叫RT  阅读(333)  评论(0编辑  收藏  举报