完整的通过逆波兰式求值

这里我自己写了个栈,其实本质上自己写的栈比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 
#include 
#include 

#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);
	}
}

你可能感兴趣的:(完整的通过逆波兰式求值)