实验5 用栈来实现简单运算(有括号)

0x01 实验目的

掌握堆栈的使用。

0x02 实验内容

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

0x03 实验过程

中缀表达式转后缀表达式(思路)

参考:https://blog.csdn.net/crr411422/article/details/130306750

我们把平时所用的标准四则运算表达式,即“9+(3-1)×3+10÷2”叫做中缀表达式。因为所有的运算符号都在两数字的中间,现在我们的问题就是中缀到后缀的转化。
中缀表达式“9+(3-1)×3+10÷2”转化为后缀表达式“9 3 1-3+10 2/+”*
规则:

  • 遇到数字就直接输出到后缀表达式中,遇到操作符就判断其优先级,并将其压入栈中。
  • 如果栈顶元素的优先级大于等于当前操作符(在减号入栈时,如果栈中有加号也要出栈),则先将栈顶元素弹出(直到有一个优先级小于该符号的符号,或者栈空或者栈顶元素为“(”在多个括号复合时会遇到如“(((4+3)*3+5)+2)*3 ”)并输出到后缀表达式中,再将当前操作符压入栈中。
    • P.s.:确保大的优先级先出去,同样的优先级,先进来的先出去,括号优先级最高,所以一旦完成就把符号出去。
  • 如果遇到了左括号,则直接将其压入栈中,如果遇到了右括号,则弹出栈中的元素,直到遇到了左括号为止,并将这些元素输出到后缀表达式中。
  • 最后,将栈中剩余的元素依次弹出,并输出到后缀表达式中。

0x04 完整代码

#include <bits/stdc++.h>
using namespace std;
int m = 0;
int n = 0;
//template is necessary
template <typename T>
class Stack {
	public:
		//necessary
		Stack(int size);
		~Stack();
		bool isEmpty() {
			return top == -1;
		}
		bool isFull() {
			return top == max;
		}
		void push(T c);
		T pop();
		T Top();
	private:
		int max;
		int top;
		T* values;
};
template <typename T>
Stack<T>::Stack(int size) {
	max = size - 1;
	top = -1;
	values = new T[size];
}
template <typename T>
Stack<T>::~Stack() {
	delete[] values;
}
template <typename T>
void Stack<T>::push(T c) {
	if(isFull()) {
		cout<<"Full"<<endl;
	} else {
		values[++top] = c;
	}
}
template <typename T>
T Stack<T>::pop() {
	if(isEmpty()) {
		return -1;
	} else {
		return values[top--];
	}
}
template <typename T>
T Stack<T>::Top() {
	return values[top];
}
int main() {
	int sum = 0;
	Stack<char> stack(100);
	cout<<"Input"<<endl;
	string back = "";
	string s;
	cin>>s;
  //中缀表达式转后缀表达式
	for(int i = 0; i < s.length(); i++) {
		if((int)s.at(i) >= 48 && (int)s.at(i) <= 57)
			back += s.at(i);
		switch(s.at(i)) {
			case '(':
				stack.push(s.at(i));
				break;
			case ')':
				while(stack.Top() != '(') {
					back += stack.pop();
				}
				stack.pop();
				break;
			case '+':
				//special
				if(stack.Top() != '*' && stack.Top() != '/' && stack.Top() != '-') stack.push(s.at(i));
				else {
					//notice
					while(stack.isEmpty() == false && stack.Top() != '(') {
						back += stack.pop();
					}
					stack.push(s.at(i));
				}
				break;
			case '-':
				if(stack.Top() != '*' && stack.Top() != '/') stack.push(s.at(i));
				else {
					//notice
					while(stack.isEmpty() == false && stack.Top() != '(') {
						back += stack.pop();
					}
					stack.push(s.at(i));
				}
				break;
			case '*':
			case '/':
				stack.push(s.at(i));
				break;
		}
	}
  //将还在栈中的运算符一个个弹出
	while(stack.isEmpty() == false) {
		back += stack.pop();
	}
	//cout<<back<<endl; 
	cout<<"Output"<<endl;
	Stack<int> ans(100);
	for(int i = 0; i < back.length(); i++) {
		if((int)back.at(i) >= 48 && (int)back.at(i) <= 57) {
			ans.push(int(back.at(i)) - 48);
		}

		switch(back.at(i)) {
			case '+':
				m = ans.pop();
				n = ans.pop();
				ans.push(n + m);
				break;
			case '-':
				m = ans.pop();
				n = ans.pop();
				ans.push(n - m);
				break;
			case '*':
				m = ans.pop();
				n = ans.pop();
				ans.push(n * m);
				break;
			case '/':
				m = ans.pop();
				n = ans.pop();
				ans.push(n / m);
				break;
		}
	}
	cout<<"="<<ans.pop()<<endl;
	cout<<"End"<<endl;
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值