顺序栈实现表达式求值

/*
* Created by Microsoft Visual Studio 2013
* @author: Teresa
* @date: 2017-10-07
* @description: 表达式求值
*/

#include 
#include 
/*函数状态码*/
#define TRUE 1	//成功
#define OK 1
#define FALSE 0	//失败 
#define ERROR 0	//错误 
#define INFEASIBLE -1	//不可行的
#define OVERFLOW -2 	//溢出

#define STACK_INIT_SIZE 100	//存储空间初试分配量
#define STACKINCREMENT 10	//存储空间分配增量

typedef double OpndType;		//	操作数栈存放的数据类型
typedef char OptrType;		//	操作符栈存放的数据类型
typedef int Status;	//函数的返回值类型 


/*操作符栈*/
typedef struct{
	OptrType *base;   //栈底指针,始终指向栈底,如果为null说明栈不存在
	OptrType *top; //栈顶指针,当top == base时,为空栈;
	int stackSize; //当前已分配的存储空间,以元素为单位
}OptrStack;
//top-base为当前栈中的元素个数

/*操作数栈*/
typedef struct{
	OpndType *base;
	OpndType *top;
	int stackSize;
}OpndStack;
	

/*操作符栈操作*/
//构造一个空栈
Status InitOptrStack(OptrStack &S){
	S.base = (OptrType *)malloc(STACK_INIT_SIZE*sizeof(OptrType));
	if (!S.base)
		exit(ERROR);
	S.top = S.base;	//栈顶指向栈底
	S.stackSize = STACK_INIT_SIZE;
	return OK;
}
//判断S是否为空栈
Status OptrStackEmpty(OptrStack &S){
	if (S.top == S.base)
		return TRUE;
	else
		return FALSE;
}
//若栈不为空 则e返回S的栈顶元素 并返回OK 否则ERROR
Status GetOptrTop(OptrStack S, OptrType &e){
	if (S.top > S.base){
		e = *(S.top - 1);
		return OK;
	}
	else
		return ERROR;
}
//插入e为新的栈顶元素
Status OptrPush(OptrStack &S, OptrType e){
	if (S.top - S.base == S.stackSize){
		//栈满 追加存储空间
		S.base = (OptrType*)realloc(S.base, (S.stackSize + STACKINCREMENT)*sizeof(OptrType));
		if (!S.base)
			exit(ERROR);
		S.top = S.base + S.stackSize;	//修改栈顶指针
		S.stackSize += STACKINCREMENT;	//更新容量
	}
	*(S.top++) = e;
	return OK;
}
//若栈不为空 则删除S的栈顶元素 用e返回其值 并返回OK 否则返回ERROR
Status OptrPop(OptrStack &S, OptrType &e){
	if (S.top == S.base) return ERROR;
	e = *--S.top;
	return OK;
}

/*操作数栈操作*/
//构造一个空栈
Status InitOpndStack(OpndStack &S){
	S.base = (OpndType *)malloc(STACK_INIT_SIZE*sizeof(OpndType));
	if (!S.base)
		exit(ERROR);
	S.top = S.base;	//栈顶指向栈底
	S.stackSize = STACK_INIT_SIZE;
	return OK;
}
//判断S是否为空栈
Status OpndStackEmpty(OpndStack &S){
	if (S.top == S.base)
		return TRUE;
	else
		return FALSE;
}
//若栈不为空 则e返回S的栈顶元素 并返回OK 否则ERROR
Status GetOpndTop(OpndStack S, OpndType &e){
	if (S.top > S.base){
		e = *(S.top - 1);
		return OK;
	}
	else
		return ERROR;
}
//插入e为新的栈顶元素
Status OpndPush(OpndStack &S, OpndType e){
	if (S.top - S.base == S.stackSize){
		//栈满 追加存储空间
		S.base = (OpndType*)realloc(S.base, (S.stackSize + STACKINCREMENT)*sizeof(OpndType));
		if (!S.base)
			exit(ERROR);
		S.top = S.base + S.stackSize;	//修改栈顶指针
		S.stackSize += STACKINCREMENT;	//更新容量
	}
	*(S.top++) = e;
	return OK;
}
//若栈不为空 则删除S的栈顶元素 用e返回其值 并返回OK 否则返回ERROR
Status OpndPop(OpndStack &S, OpndType &e){
	if (S.top == S.base) return ERROR;
	e = *--S.top;
	return OK;
}

//划分优先级
int Rank(OptrType e){
	switch (e){
	case '#':
		return 0; break;
	case '(':
		return 1; break;
	case '+':
	case '-':
		return 2; break;
	case '*':
	case '/':
		return 3; break;
	default:
		return INFEASIBLE; break;
	}
}

//运算操作
OpndType Operate(OpndType a, OpndType b, OptrType op){
	OpndType c;
	switch (op){
	case '+':
		c = a + b;
		break;
	case '-':
		c = a - b;
		break;
	case '*':
		c = a*b;
		break;
	case '/':
		if (b == 0){
			printf("分母为0");
			return ERROR;
		}
		else
			c = a / b;
		break;
	default:
		printf("输入的字符不合法");
		break;
	}
	return c;
}
Status StackTraverse(OpndStack S){
	while (S.top > S.base){
		printf("%d ", *(S.base++));
	}
	printf("\n");
	return OK;
}

Status StackTraverse1(OptrStack S){
	while (S.top > S.base){
		printf("%c ", *(S.base++));
	}
	printf("\n");
	return OK;
}

//将存储表达式的字符数组压入栈内
void HandleStr(char str[]){
	OptrStack optr;	//定义操作符栈
	OpndStack opnd;	//定义操作数栈
	OptrType op;
	InitOptrStack(optr);	//初始化操作符栈
	InitOpndStack(opnd);	//初始化操作数栈
	int i, j;
	OpndType f, a, b,result;
	char num[100];
	OptrPush(optr, '#');
	for (i = 0; str[i]; i++){
		switch (str[i]){
		case '+':
		case '-':
			/*先判断当前运算符与操作符栈栈顶元素的优先级,
			如果高于栈顶元素,则入栈;
			小于栈顶元素,则从操作数栈中依次出两个数,
			并将操作符栈中栈顶元素出栈,再将从操作数栈中出的两个数,
			按从操作符栈栈中出的运算符运算,并将结果压入操作数栈中,
			再将当前的操作符压入操作符栈中。*/
			GetOptrTop(optr, op);
			if (op == '#' || op == '('){
				OptrPush(optr, str[i]);
			}
			else{
				 OpndPop(opnd, a);
				 OpndPop(opnd, b);
				 OptrPop(optr, op);
				 OpndPush(opnd, Operate(b, a, op));
				 OptrPush(optr, str[i]);
			}
			break;
		case '*':
		case '/':
			GetOptrTop(optr, op);
			if (Rank(str[i]) > Rank(op) || op == '('){
				OptrPush(optr, str[i]);
			}
			else{
				OpndPop(opnd, a);
				OpndPop(opnd, b);
				OptrPop(optr, op);
				OpndPush(opnd, Operate(b, a, op));
				OptrPush(optr, str[i]);
			}
			break;
		case '(':
			OptrPush(optr,str[i]);
			break;
		case ')':
			GetOptrTop(optr, op);
			while (op != '('){
				OpndPop(opnd, a);
				OpndPop(opnd, b);
				OptrPop(optr, op);
				OpndPush(opnd, Operate(b, a, op));
				GetOptrTop(optr, op);
			}
			OptrPop(optr, op);
			break;
		default:
			j = 0;
			do{
				num[j] = str[i];
				i++;
				j++;
			} while (str[i] > '0' && str[i] < '9' || str[i] == '.');
			num[j] = '\0';
			i--;
			f = atof(num);
			OpndPush(opnd, f);
			break;
		}
	}
	GetOptrTop(optr, op);
	while (op != '#'){
		OpndPop(opnd, a);
		OpndPop(opnd, b);
		OptrPop(optr, op);
		OpndPush(opnd, Operate(b, a, op));
		GetOptrTop(optr, op);
	}
	GetOpndTop(opnd, result);
	printf("表达式%s=%g\n", str, result);
}

int main(){
	char str[100];
	printf("请输入表达式:\n");
	scanf("%s", str);
	HandleStr(str);
	return 0;
}

你可能感兴趣的:(数据结构)