山东大学数据结构实验五堆栈的应用

6、 输入一个数学表达式(假定表达式输入格式合法),计算表达式结果并输出。
7、 数学表达式由单个数字和运算符“+”、“-”、“*”、“/”、“(、) ”构成,例如 2 + 3 * ( 4 + 5 ) - 6 / 4。
8、 变量、输出采用整数,只舍不入。

#include<iostream>
using namespace std;
#define MAX_SIZE 100

//先准备一下栈
//这个好像是用数组写的栈
template<class T>
class Stack
{
public:
	Stack();
	/*~Stack();*/
	~Stack() {}

	void push_back(T data1);
	
	T Front();
	T pop();
	int GetSize();
	void Clear();
	bool empty();
private:
	T data[1024];
	int size;
};
template<class T>
Stack<T>::Stack()
{
	for (int i = 0; i < MAX_SIZE; i++)
	{
		data[i] = NULL;
	}
	size = 0;
}
//template<class T>
//Stack<T>::~Stack()
//{
//	if (this->data)
//	{
//		Clear();
//		delete []data;
//		this->size = 0;
//	}
//}
//入栈
template<class T>
void Stack<T>:: push_back(T data1)
{
	if (data1 == NULL)
	{
		return;
	}
	data[this->size] = data1;
	++this->size;
}


//返回栈顶的元素
template<class T>
T Stack<T>::Front()
{
	if (this->size == 0)
	{
		return NULL;
	}
	T temp = data[this->size - 1];
	return temp;
}
//弹栈
template<class T>
T Stack<T>::pop()
{
	if (this->size == 0)
	{
		return NULL;
	}
	T temp = this->data[this->size - 1];
	this->data[this->size - 1] = NULL;
	--this->size;
	return temp;
}
template<class T>
int Stack<T>::GetSize()
{
	return this->size;
}
template<class T>
void Stack<T>::Clear()
{
	if (this->size == 0)
	{
		return;
	}
	for (int i = 0; i < this->size; i++)
	{
		this->data[i] = NULL;
	}
	this->size = 0;
}
template<class T>
bool Stack<T>::empty()
{
	if (this->size == 0)
	{
		return true;
	}
	return false;
}

//---------------以上是栈的准备---------------------
//我看着很多大佬用链表的栈。。没事数组也挺好,能用就行
//----------------难的来啦--------------------------


//判断两个符号谁的优先级高
//如果前面的高或者两个一样高则返回true
//总之就是可以正常从左往右算就很开心,返回true
//遇到绊子不能开心地从左往右滚雪球似的算那就不开心啦,返回false
bool decide(char char1, char char2)
{
	if ((char1 == '*') || (char1 == '/') )return true;
	if ((char1 == '+' || char1 == '-')&&(char2 == '+'||char2 == '-'))return true;
	return false;
}

bool isNum(char onechar)
{
	int num = onechar;
	if (num >= 48 && num <= 57)return true;
	return false;
}

//计算的主力军
void suan(string s,int length)
{
	Stack<int> stackInt;//存储数字(里面是数字)
	Stack<char> stackelse;//存储运算符(里面是字符)

	char temp1;//在s中当前遍历到的字符
	char temp2;//操作符那个栈的栈顶字符


	for (int i = 0; i < length; i++)
	{
		temp1 = s[i];
		
		//如果遍历到的字符是数字
		if (isNum(temp1))
		{
			stackInt.push_back(temp1 - 48);
		}
		else if (temp1 == '(')
		{
			stackelse.push_back(temp1);
		}
		else if (temp1 == ')')//右括号不入栈
		{
			 temp2 = stackelse.Front();//这是栈里弹出的第一个元素
			int x, y, res;
			
			while (temp2 != '(')
			{
				
				x = stackInt.pop();
				y = stackInt.pop();

				if (temp2 == '*')res = x * y;
				if (temp2 == '+')res = x + y;
				if (temp2 == '/')res = y / x;
				if (temp2 == '-')res = y - x;

			
				
				stackInt.push_back(res);

				stackelse.pop();
				temp2 = stackelse.Front();
			}
			int t=stackelse.pop();//将(弹出栈
		
		}
		else {//是运算符

		      temp2 = stackelse.Front ();
			  int res=0;
		   while (decide(temp2, temp1))//如果前面的运算符比当前的运算符厉害,也就是可以放心滴从左到右滚雪球
		   {
			   int x, y;
			  
				   x = stackInt.pop();
				   y = stackInt.pop();

				
				   if (temp2 == '*')res = x * y;
				   if (temp2 == '+')res = x + y;
				   if (temp2 == '/')res = y / x;
				   if (temp2 == '-')res = y - x;
				 
				  
			      stackInt.push_back(res);
				
				  stackelse.pop();
				  temp2 = stackelse.Front();
		   }
		   stackelse.push_back(temp1);//将未运算的符号压入栈中


	   }
	}
	 temp2 = stackelse.Front();
	int res = 0;
	while (!stackelse.empty())
	{
		int x, y;
		x = stackInt.pop();
		y = stackInt.pop();

        

		if (temp2 == '*')res = x * y;
		if (temp2 == '+')res = x + y;
		if (temp2 == '/')res = y / x;
		if (temp2 == '-')res = y - x;

		stackInt.push_back(res);
		
		stackelse.pop();
		temp2 = stackelse.Front();
	}

	cout << stackInt.Front() << endl;
	/*if (!stackInt.empty())
	{
		cout << stackInt.pop() << endl;
	}*/

	
}

int main()
{
	cout << "Input" << endl;
	string s;
	cin >> s;

	int length = s.length();
	cout << "Output" << endl;
	suan(s, length);
	cout << "End" << endl;
	return 0;
}


在这里插入图片描述

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值