实验原理
代码思路
-
使用两个顺序栈编程,一个顺序栈用来存储操作数,一个顺序栈用来存储操作符
-
关键为表达式求值函数的编写
-
对该函数,循环结束条件为栈顶元素为’#’,且读入的字符也为’#’
-
循环体
- (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主:跟懒猫老师快乐数据结构