实验原理
代码思路
-
使用两个顺序栈编程,一个顺序栈用来存储操作数,一个顺序栈用来存储操作符
-
关键为表达式求值函数的编写
-
对该函数,循环结束条件为栈顶元素为’#’,且读入的字符也为’#’
-
循环体
- (1)判断是否为操作数,是操作数,则压入栈中读取下一个字符
- (2)是操作符,则比较操作符的优先级
- 操作符栈栈顶元素用t1表示,读入的字符用t2表示
- (a)t1>t2,则t1弹出操作符栈,与此同时操作数栈弹出两个元素,进行运算操作,将结果压入操作数栈中,注意该操作不读取下一个字符
- (b)t1 = t2,操作符栈弹出栈顶元素,读取下一个字符
- ©t1<t2,t2压入操作符栈中,读取下一个字符
-
接下来便是precede函数,isOptr函数,operate函数的编写
-
实验代码(采用C++面向对象编程)
stack.h
#ifndef STACK_H__
#define STACK_H__
#define MAXSIZE 20
template<class DataType>
class Stack
{
private:DataType *data;int top;int capacity;
public:Stack();//无参构造函数Stack(int sz);//有参构造函数~Stack();//析构函数DataType Pop();//弹出元素void Push(DataType elem);//压入元素DataType getTop();//得到栈顶元素bool isEmpty();//判断栈是否为空bool isFull();//判断栈是否为满class Empty{};//设置内置异常类class Full {};
};
typedef Stack<char> CharStack;
typedef Stack<int> IntStack;
int evaluatExpression(IntStack &opndStack, CharStack &optrStack);
#endif
stack.cpp
#include<iostream>
using namespace std;
#include "stack.h"template<class DataType>
Stack<DataType>::Stack()
{data = new DataType[MAXSIZE];top = -1;capacity = MAXSIZE;
}template<class DataType>
Stack<DataType>::Stack(int sz)
{data = new DataType[sz];top = -1;capacity = sz;
}template<class DataType>
Stack<DataType>::~Stack()
{delete[] data;
}template<class DataType>
DataType Stack<DataType>::Pop()
{if (isEmpty()){throw Empty();}else{return data[top--];}
}template<class DataType>
void Stack<DataType>::Push(DataType elem)
{if (isFull()){throw Full();}else{data[++top] = elem;}
}template<class DataType>
DataType Stack<DataType>::getTop()
{if (isEmpty()){throw Empty();}else{return data[top];}
}template<class DataType>
bool Stack<DataType>::isEmpty()
{if (top == -1){return true;}else{return false;}
}template<class DataType>
bool Stack<DataType>::isFull()
{if (top == MAXSIZE - 1){return true;}else{return false;}
}template class Stack<char>;
template class Stack<int>;int operate(int num1,char optr, int num2)
{switch (optr){case '+':return num1 + num2;break;case '-':return num2 - num1;break;case '*':return num2 * num1;break;case '/':return num2 / num1;break;}
}bool isOptr(char ch)
{switch (ch){case '+':return true;break;case '-':return true;break;case '*':return true;break;case '/':return true;break;case '(':return true;break;case ')':return true;break;case '#':return true;break;default:return false;break;}
}
//判断操作符的优先级,t1优先级高于t2优先级返回'>'
char precede(char t1, char t2)
{char f;switch (t1){case '+':if (t2 == '*' || t2 == '/' || t2 == '('){f = '<';}else{f = '>';}break;case '-':if (t2 == '*' || t2 == '/' || t2 == '('){f = '<';}else{f = '>';}break;case '*':if (t2 == '('){f = '<';}else{f = '>';}break;case '/':if (t2 == '('){f = '<';}else{f = '>';}break;case '(':if (t2 == ')'){f = '=';}else if (t2 == '#'){f = ' ';}else{f = '<';}break;case ')':if (t2 == '('){f = ' ';}else{f = '>';}break;case '#':if (t2 == '#'){f = '=';}if (t2 == ')'){f = ' ';}else{f = '<';}break;}return f;
}
int evaluatExpression(IntStack &opndStack, CharStack &optrStack)
{char ch,optr;int num1, num2,res,temp;optrStack.Push('#');int isNum = 0;//判断前一个字符是否为数字cin >> ch;//循环结束条件,栈顶元素为'#',且读入的字符为'#'while (ch != '#' || optrStack.getTop() != '#'){if (!isOptr(ch))//操作数,压入数据栈中{if (isNum == 1){temp = opndStack.Pop();temp = temp * 10 + (ch - '0');opndStack.Push(temp);isNum = 1;cin >> ch;}else {isNum = 1;opndStack.Push(ch - '0');cin >> ch;}}else//操作符,比较优先级{isNum = 0;switch (precede(optrStack.getTop(),ch)){case '>'://栈顶元素出栈,操作数栈弹出2个元素num1 = opndStack.Pop();num2 = opndStack.Pop();/*cout << num1 << "\t";cout << num2 << endl;*/optr = optrStack.Pop();res = operate(num1, optr, num2);opndStack.Push(res);break;case '<':optrStack.Push(ch);cin >> ch;break;case '=':optrStack.Pop();cin >> ch;break;}}}return opndStack.Pop();
}
main.c
#include<iostream>
using namespace std;
#include "stack.h"
//表达式求值
int main()
{CharStack optrStack;IntStack opndStack;NELEMTYPE res;cout << "请输入算数表达式以#结束" << endl;res = EvaluateExpression(optrStack, opndStack);cout << res << endl;return 0;
}
运行结果
参考链接
b站up主:laura柳
b站up主:跟懒猫老师快乐数据结构