#include<iostream>
#include<string>
#include<algorithm>
#include<iomanip>
#include<conio.h>
#include<vector>
using namespace std;
const int N = 1e5 + 10;
int a[200];
typedef struct Stack{
char date;
Stack *next;
}Stack,*LinkStack;
void Ini(LinkStack *S)
{
(*S) = (LinkStack)malloc(sizeof(Stack));
(*S)->next = NULL;
}
void Push(LinkStack S,char x)
{
Stack* New,*P = S;
New = (LinkStack)malloc(sizeof(Stack));
New->date = x;
New->next = P->next;
P->next = New; // 头插法建立Stack容器
}
char Top(LinkStack S)
{
return S->next->date;
}
void Pop(LinkStack S)
{
S->next = S->next->next;
}
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
Stack ovs,optr;
LinkStack OVS = &ovs,OPTR =&optr;
Ini(&OVS),Ini(&OPTR);
a['#'] = 0;
a['+'] = 1;
a['-'] = 1;
a['*'] = 2;
a['/'] = 2;
a['^'] = 3; // 打好的优先级表
Push(OPTR,'#'); // 先在空的OPTR栈中压入一个0级的运算符 方便第一个运算符的压入
char str[N];
int flag = 1;
do{
char ch;
cin >> ch;
if(ch != '+' && ch != '-' && ch != '*' && ch != '/' && ch != '^' && ch != '#') // num
{
Push(OVS,ch); // 输入的如果是数字的话 直接压入OVS栈中
}
else // operator
{
if(a[ch] >= a[Top(OPTR)])
{
Push(OPTR,ch); // 如果现在输入的操作符的优先级高于或者等于现在OPTR栈顶的操作符,则直接压入
}
else
{
while(a[ch] < a[Top(OPTR)]) // 进行循环操作 确保现在准备压入的这个操作符的优先级别低到可以压入OPTR栈中(将优先级高的运算符号对应的操作数先进行运算)
{
int a = Top(OVS) - '0';
Pop(OVS);
int b = Top(OVS) - '0';
Pop(OVS);
char Ch = Top(OPTR);
Pop(OPTR);
int sum = 0;
if(Ch == '+') sum = a + b;
else if(Ch == '-') sum = a - b;
else if(Ch == '*') sum = a * b;
else if(Ch == '/') sum = a / b;
else if(Ch == '^') sum = pow(a,b);
Push(OVS,sum + '0'); // 将运算的结果压入OVS栈中 作为一个降了级的操作数
}
Push(OPTR,ch); //压入现在的操作数
}
}
if(ch == '#')
{
cout << Top(OVS) - '0' << endl;
flag = 0;
}
}while(flag == 1);
return 0;
}
之前写的使用STL函数库的版本中,在计算过程中的ch其实应该改位Ch比较高,虽然在作用域中会被覆盖,但是避免引起二义性