0x01 实验目的
掌握堆栈的使用。
0x02 实验内容
- 输入一个数学表达式(假定表达式输入格式合法),计算表达式结果并输出。
- 数学表达式由单个数字和运算符“+”、“-”、“*”、“/”、“(、) ”构成,例如 2 + 3 * ( 4 + 5 ) - 6 / 4。
- 变量、输出采用整数,只舍不入。
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;
}