这里我自己写了个栈,其实本质上自己写的栈比STL自带的栈的效率要高;
然后用Sstring存储输入当中的int
里面有两个递归
一个是 在出栈过程当中根据栈头的运算符的优先级判断是否出栈
一个是求完了逆波兰表达式之后递归求值,每次运算一次之后,int数组就向前移动两个
``int numt = 0;
void PushSstring(Sstring &S, char c,bool isNum = false)
{
if(S.index >= S.length - 1)
{
S.base = (ElemType*)realloc(S.base,(S.length + STACKSIZE_INCREMENT)*sizeof(ElemType));
S.length += STACKSIZE_INCREMENT;
}
if(isNum){
if(numt == 1)
{
S.index++;
S.base[S.index] = 0;
}
// cout << "S.base["<< S.index << "]:" << S.base[S.index] << " c:" << c << endl;
S.base[S.index] = S.base[S.index]*10 + (int)c - 48;
// cout << " S.base["<< S.index << "]:" << S.base[S.index] << endl;
}
else {
// cout << "c:" << c << " intc:" << (int)c << endl;
S.index++;
S.base[S.index] = -(int)c;
}
}
Sstring TransformRPN(SqStack &S,char buffer[])
{
int i = 0;
Sstring rpn; InitSstring(rpn);
while(buffer[i] != '\0')
{
char ch = buffer[i];
int prior = GetPriority(ch);
if (prior == 0){
numt++;
PushSstring(rpn,ch,true);
}
else {
numt = 0;
if (prior == 4)//GetPriority('(') = 4;
{
PushStack(S, ch);
}
else if (prior == 3)//GetPriority(')') = 3;
{
RecurvePop(S, ch, rpn);
PopStack(S);
}
else {
int topprior = GetPriority(*(S.top));
if (prior >= topprior){
RecurvePop(S, ch, rpn);
}
PushStack(S, ch);
}
}
i++;
}
RecurvePop(S, '^', rpn);
return rpn;
}
int CalculateRPN(Sstring &rpn)
{
if(rpn.index == 1){
return rpn.base[1];
}
int i = 1;
while(rpn.base[i] >= 0)
{
i++;
}
char c = (char)(-rpn.base[i]);
// cout << rpn.base[i-2] << " " << c << " " << rpn.base[i-1] << endl;
if(c == '+') rpn.base[i-2] += rpn.base[i-1];
else if(c == '-') rpn.base[i-2] -= rpn.base[i-1];
else if(c == '*') rpn.base[i-2] *= rpn.base[i-1];
else if(c == '/') rpn.base[i-2] /= rpn.base[i-1];
rpn.index -= 2;
for(int j = i-1; j <= rpn.index; j++)
{
rpn.base[j] = rpn.base[j+2];
}
return CalculateRPN(rpn);
}
int main()
{
SqStack S;
if(InitStack(S) != OK) return 0;
char buffer[10000];
cin >> buffer;
PushStack(S,'#');
Sstring rpn = TransformRPN(S,buffer);
//逆波兰表达式 ,通过Int数组存储数字和用负数表示加减乘除
//这里是输出波兰表达式
// for(int i = 1; i <= rpn.index; i++)
// {
// if(rpn.base[i] < 0) cout << (char)(-rpn.base[i]) << " ";
// else cout << rpn.base[i]<< " ";
// }
// cout << endl;
cout << CalculateRPN(rpn) << endl;
return 0;
}
这里是前面的代码
#include <iostream>
#include <stdio.h>
#include <malloc.h>
#define STACK_INIT_SIZE 100
#define STACKSIZE_INCREMENT 10
#define SSTRING_INIT_SIZE 100
using namespace std;
typedef int ElemType;
typedef enum{
OK = 1,
ERROR = -1,
TRUE = 2,
FALSE = 3
}Status;
struct SqStack
{
ElemType *base;
ElemType *top;
int stackSize;
};
struct Sstring{
ElemType *base;
int index;
int length;
};
Status InitStack(SqStack &S)
{
S.base = (ElemType*)malloc(STACK_INIT_SIZE*sizeof(ElemType));
if(!S.base) return ERROR;
S.top = S.base;
S.stackSize = STACK_INIT_SIZE;
return OK;
}
Status PushStack(SqStack &S,ElemType e)
{
if(S.top - S.base >= S.stackSize)
{
S.base = (ElemType*)realloc(S.base,(S.stackSize + STACKSIZE_INCREMENT)*sizeof(ElemType));
S.stackSize += STACKSIZE_INCREMENT;
}
// cout <<"S.top:"<< S.top << " S.base:" << S.base << " S.top - S.base:" << S.top - S.base << endl;
S.top++;
*(S.top) = e;
// printf("S.top:%p S.base:%p S.top - S.base:%d",S.top,S.base,S.top - S.base);
// printf(" *S.top:%c\n",e);
return OK;
//(1+2*(1+2*(1+2*(1+2*8))))
//2*(1+2*(1+2*8))
}
Status PopStack(SqStack &S)
{
if(S.top <= S.base) return ERROR;
S.top--;
return OK;
}
Status DelStack(SqStack &S)
{
free(S.base);
free(S.top);
S.base = S.top = NULL;
if(!S.base && !S.top) return ERROR;
return OK;
}
Status InitSstring(Sstring &S)
{
S.base = (ElemType*) malloc (SSTRING_INIT_SIZE*sizeof(ElemType));
if(!S.base) return ERROR;
S.index = 0;
S.length = SSTRING_INIT_SIZE;
return OK;
}
int GetPriority(char c)
{
switch(c){
case '*':
return 1;
break;
case '/':
return 1;
break;
case '+':
return 2;
break;
case '-':
return 2;
break;
case ')':
return 3;
break;
case '(':
return 4;
break;
case '^':
return 5;
break;
case '#':
return 6;
break;
default:
break;
}
return 0;
}
void RecurvePop(SqStack &S, ElemType e,Sstring &rpn)
{
int topprior = GetPriority(*S.top);
int prior = GetPriority(e);
if (topprior > prior ) return;
else {
PushSstring(rpn,*(S.top));
PopStack(S);
RecurvePop(S, e, rpn);
}
}