顺序栈实现算术表达式

实验要求:不能使用c++的stack
在这里插入图片描述

#include <iostream>
#include <string>
#include<cctype>
#include<stack>
const int maxSize = 50;
const int stackIncreament = 20;
using namespace std;
template <class T>
class SeqStack {
public:
	SeqStack(int sz = 50);        // 创建一个空栈
	~SeqStack() { delete[] elements; } // 析构函数
	void Push(const T& x);          // 入栈::如果IsFull(),则溢出处理;否则把x插入到栈的顶端
	bool Pop(T& x);                 // 出栈(删除栈顶元素):如果IsEmpty(),则不执行退栈,返回false;否则退掉位于栈顶的元素,返回true,退出的元素用x返回
	T getTop();              // 读栈顶元素(不删除栈顶元素):通过x返回栈顶元素
	bool IsEmpty() const { return (top == -1) ? true : false; } // 判空:栈中个数为0,则返回true,否则返回false
	bool IsFull() const { return (top == maxSize - 1) ? true : false; } // 判满:如果栈中元素等于maxSize,则返回true,否则false
	int getSize() const { return top + 1; } // 返回栈中元素个数
	void MakeEmpty() { top = -1; }       // 清空栈中内容
private:
	T* elements;                    // 存放栈中元素的栈数组
	int top;                        // 栈顶指针
	int maxSize;                    // 栈最大可容纳元素    
	void overflowProcess();         // 栈的溢出处理
};

template <class T>
SeqStack<T>::SeqStack(int sz) : top(-1), maxSize(sz) {
	elements = new T[maxSize];       // 创建栈的数组空间
	      
}

template <class T>
void SeqStack<T>::overflowProcess() {
	// 扩充栈的存储空间
	T* newArray = new T[maxSize + stackIncreament];
	if (newArray == NULL) {
		cout << "存储分配失败" << endl;
		exit(1);
	}
	for (int i = 0; i <= top; i++) {
		newArray[i] = elements[i];
	}
	maxSize = maxSize + stackIncreament;
	delete[] elements;
	elements = newArray;
}
template <class T>
void SeqStack<T>::Push(const T& x) {
	if (IsFull() == true)
		overflowProcess();  // 栈满则溢出处理
	elements[++top] = x;    // 栈顶指针先加1,再进栈
}

template <class T>
bool SeqStack<T>::Pop(T& x) {
	if (IsEmpty() == true)
		return false;
	x = elements[top--];   // 栈顶指针退一,把栈顶元素给删除了
	return true;
}

template <class T>
T SeqStack<T>::getTop() {
	if (IsEmpty() == true)
		return T();
	T x = elements[top];          // 返回栈顶元素,栈顶元素没有删除
	return x;
}


// 定义运算符优先级函数
int isp(char ch) {
	if (ch == '#' || ch == '(') return 0;
	if (ch == '+' || ch == '-') return 1;
	if (ch == '*' || ch == '/') return 2;
	return -1; // 其他情况,例如数字
}

int icp(char ch) {
	if (ch == '#' || ch == '(') return 3;
	if (ch == '+' || ch == '-') return 1;
	if (ch == '*' || ch == '/') return 2;
	return -1; // 其他情况,例如数字
}
class Calculator
{
public:
	Calculator() {};
	void Run(string);
	void Clear();
	SeqStack<double>s;
	void DoOperator(char op);
	void AddOperand(char value);
	bool get2Operands(double& left, double& right);
};

bool Calculator::get2Operands(double& left, double& right)
{
	if (s.IsEmpty() == true)
	{
		cerr << "缺少右操作数" << endl;
		return false;
	}
	s.Pop(right);
	if (s.IsEmpty() == true) 
	{
		cerr << "缺少左操作数" << endl;
	}
	s.Pop(left);
}
void Calculator::DoOperator(char op)
{
	double left, right, value;
	int result;
	result = get2Operands(left, right);
	if (result == true)
	{
		switch (op)
		{
		case'+':
			value = left + right;
			s.Push(value);
			break;
		case'-':
			value = left - right;
			s.Push(value);
			break;
		case'*':
			value = left * right;
			s.Push(value);
			break;
		case'/':
			if (right == 0.0)
			{
				cerr << "Divide by 0!" << endl;
				Clear();
			}
			else
			{
				value = left / right;
				s.Push(value);
			}
			break;
		}
	}
	else Clear();

}
void Calculator::AddOperand(char value)
{
	value = value - '0';
	s.Push(value);
}
void Calculator::Clear()
{
	s.MakeEmpty();
}
string infixToPostfix(string expression) {
	SeqStack<char> s;  // 创建操作符栈,用于存储操作符
	string postfix = "";  // 初始化后缀表达式为空字符串
	char op;
	for (int i = 0; i < expression.length(); i++) {
		char ch = expression[i];

		if (isdigit(ch)) {
			// 如果是数字,直接添加到后缀表达式中
			postfix += ch;
		}
		else if (ch == '(') {
			// 如果是左括号,将其推入操作符栈
			s.Push(ch);
		}
		else if (ch == ')') {
			// 如果是右括号,弹出操作符栈中的操作符并添加到后缀表达式,直到遇到左括号
			while (!s.IsEmpty() && s.getTop() != '(') {
				s.Pop(op);
				postfix += op;
				
			}
			s.Pop(op);  // 弹出左括号
		}
		else {
			// 如果是操作符
			while (!s.IsEmpty() && isp(s.getTop()) >= icp(ch)) {
				// 弹出栈中优先级高于或等于当前操作符的操作符,并添加到后缀表达式中
				s.Pop(op);
				postfix = postfix + op;
			}
			// 将当前操作符推入操作符栈
			s.Push(ch);
		}
	}

	// 将剩余的操作符添加到后缀表达式
	while (!s.IsEmpty()) {
		s.Pop(op);
		postfix = postfix + op;
	}
	return postfix;
}
void Calculator::Run(string postfixExpression)
{
	for (int i = 0; i < postfixExpression.length(); i++)
	{
		char ch = postfixExpression[i];
		if (isdigit(ch))
			AddOperand(ch);          //如果字符串遇到数字的话,char转化成double;
		else if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
			DoOperator(ch);
	}
	if (!s.IsEmpty())
	{
		double result;
		s.Pop(result);
		cout << "结果为:" << result;
	}
	else
	{
		cerr << "后缀表达式无效,无法计算结果" << endl;
	}
}
int main() {
	Calculator calculator;

	while (1)
	{
		calculator.Clear();
		string infixExpression;
		cin >> infixExpression;
		string postfixExpression = infixToPostfix(infixExpression);
		cout << "中缀表达式为:" << infixExpression << endl;
		cout << "后缀表达式为: " << postfixExpression << endl;
		calculator.Run(postfixExpression);
		
	}
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值