www.pudn.com > gc.rar > GAOCHENG_STACK_EXPRESS.C


# include  
# include  
# include  
# define POW 1                //乘幂 
# define MUL 2				  //乘 
# define DIV 3                //除 
# define ADD 4                //加 
# define SUB 5                 //减 
# define Lp 6                 //左括号 
# define Rp 7                 //右括号 
# define END 8 
# define Epsilon 1e-7 
 
typedef double NODE; 
struct { 
	char op;           //操作符号,你所输入的表达式符号 
	int code;           //程序所定义的运算符内部码,也就是上面的define所定义的符号 
} opchTbl[]={{'*',2},{'/',3},{'+',4},{'-',5},{'(',6},{')',7},{'^',1},{'\n',8},{' ',-1}}; 
 
typedef struct node { 
	NODE data; 
	struct node * link; 
}LNODE; 
LNODE *optop, *numtop;  /*运算符栈,运算分量栈*/ 
 
/*链接存储栈的进栈函数*/ 
void l_push(NODE x,LNODE **toppt) 
{ 
	LNODE *p = (LNODE *)malloc(sizeof(LNODE)); 
	p->data = x; 
	p->link = *toppt; 
	*toppt = p; 
} 
 
/*链接存储栈的出栈函数*/ 
int l_pop(NODE *cp,LNODE ** toppt) 
{ 
	LNODE *p = *toppt; 
	if (*toppt == NULL) return 1;              /*空栈*/ 
	*cp = p->data; 
	*toppt = p->link; 
	free(p); 
	return 0; 
} 
 
int osp[] = {5,3,3,2,2,5,1,1},            /* ^,*,/,+,-,(,), \n的栈外优先级   */ 
    isp[] = {4,3,3,2,2,0};                /* ^,*,/,+,-,(的栈内优先级*/ 
	/*因为有运算符自右向左,有运算符自左向右运算,所以引入栈内栈外两个优先级,统一算法,方便处理*/ 
 
 
void synError() 
{ 
	double temp; 
	printf("表达式句法错!"); 
	while(optop!=NULL) l_pop(&temp,&optop); 
	while(numtop!=NULL) l_pop(&temp,&numtop); 
	exit(0); 
} 
 
double eval(char tag,double left,double right) 
{ 
	int n; 
	double result; 
	switch(tag) { 
		case POW: for (n=1,result=left;n'9') {       //这些字符都是整数的形式相比较 
		for(i=0;opchTbl[i].code != -1 && opchTbl[i].op !=c; i++); 
		if(opchTbl[i].code == -1) synError();      /*非法字符*/ 
		if(c != '\n') c = getchar();                /*c中存储下一个字符*/ 
		return opchTbl[i].code;                     /*返回运算符的内部码*/ 
	} 
	num = 0.0;                                        /*遇到数字,翻译数*/ 
	while (c>='0' && c<='9') { 
		num = RADIX * num + c - '0'; 
		c = getchar(); 
	} 
	if(c == '.') {                   //实现小数点后数值的读取 
		dradix = 1.0/RADIX; 
		c = getchar(); 
		while (c>='0' && c<='9') { 
			num = num + (c - '0') * dradix;   //我们输入的字符是asc码,所以我们要转换成数值 
			dradix /= RADIX; 
			c = getchar(); 
		} 
	} 
	*nump = num; 
	return 0; 
} 
 
void main() 
{ 
	double num,dop,operand1,operand2,res; 
	int type;       //内部码,表示加减乘除等等等等,但如果等于0,则表示输入的是一个操作数 
	char ans,op; 
	do { 
		printf("请输入表达式!\n"); 
		optop = numtop = NULL; 
		l_push(Lp,&optop);                                     /*左括号进栈*/ 
	    do c = getchar();                                       /*掠过前导空白类字符*/ 
		while (c == ' ' || c== '\n' || c =='\t'); 
		while (1) { 
			type = getToken(&num); 
			if(type == 0) l_push(num,&numtop);              /*数字进运算分量栈 */ 
			else {                                          /*如果是操作符*/ 
				if(osp[type-1]>isp[(int)optop->data-1]) l_push((double)type,&optop);/*栈外运算符进栈*/ 
				else {           /*栈外小于栈内,退栈运算,一直退到大于栈内,再依三种情况处理*/ 
					while(osp[type-1] <= isp[(int)optop->data-1] && optop->data <= 5) { 
						if(l_pop(&dop,&optop)) synError();          /*运算符出栈*/ 
						op = (char)dop; 
						if(l_pop(&operand2,&numtop)) synError; /*运算分量2出栈*/ 
						if (l_pop(&operand1,&numtop)) synError();  /*运算分量1出栈*/ 
						res=eval(op,operand1,operand2);  /*双目运算 */ 
						l_push(res,&numtop);             /*运算结果进栈*/ 
					} 
                  /*前面while循环一直退栈运算..当栈外运算符优先级大于栈内运算符优先级, 
				  ,推出while循环,将面对以下三种情况*/ 
					if(type == END) break;               /*第一种情况:一个表达式计算结束 */ 
					if(type == Rp) {                    /* 第二种情况  将栈中'('退去 */ 
					do if(l_pop(&dop,&optop)) synError(); 
					while((char)dop != Lp);          /*连续退栈至'('  */ 
					} 
					else l_push((double)type,&optop);    /*第三种情况栈外运算符进栈  */ 
 
				}//endelse 
			}//endelse 
		}//endwhile 
		if (l_pop(&operand1,&numtop)) synError();           /*计算结果出栈*/ 
		while (optop != NULL) l_pop(&dop,&optop); 
		while (numtop != NULL) l_pop(&res,&numtop); 
		printf("结果为%f\n",operand1); 
		printf("继续吗?y继续"); 
		scanf("%c",&ans); 
	}while(ans == 'y' ||ans == 'Y');//enddo 
}