实验要求:不能使用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;
}