栈的应用-表达式求值

两点建议

switch语句要规范写,不然鬼知道错哪了;

函数参数传递的顺序,从右往左,就这坑了我俩钟头;

//********************************
//welcome to use my progrem
//compiler version VC6.0
//brief introduction:for operator,'+','-','*','/','(',')','#'can be used only
//brief introduction:num type is double,better hve no more than 6 decimal places
//brief introduction:use '#' as your expression's first and final
//brief introduction:expression can not longer than 50 word
//********************************

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEFSIZE 20

typedef double ELEMTYPE;//top&base's type can be changed for use
typedef struct
{
	ELEMTYPE *base;
	ELEMTYPE *top; 
	int stackSize;
}SQSTACK,*SQSTACKP;

SQSTACKP initstack(SQSTACKP sqstack);
int isfull(SQSTACKP sqstack);
int isempty(SQSTACKP sqstack);
int push(SQSTACKP sqstack,ELEMTYPE elem);
ELEMTYPE* pop(SQSTACKP sqstack);
ELEMTYPE* gettop(SQSTACKP sqstack);
int addroom(SQSTACKP sqstack,int howmuch);
char* numjudge(SQSTACKP sqstack,char *ch);
int oprchange(char *ch);
int oprpriority(int ch,int top);
int calculation(SQSTACKP sqstack,double *left,int opr,double *right);
int expressionevaluation(char *ques,double *answ);

void main()
{
	char buf[50]="\0",*ques=buf+1;
	double *answ=(double*)malloc(sizeof(double));
	
	printf("************************************************************\n");
	printf("welcome to use my progrem\n");
	printf("please read brief introduction before use\n");
	printf("for operator,'+','-','*','/','(',')','#'can be used only\n");
	printf("use '#' as your expression's first and final\n");
	printf("num type is double,better have no more than 6 decimal places\n");
	printf("************************************************************\n");
	
	printf("press enter to start/continue;input any else to exit");
	if(getchar()=='\n') 
	{
		while(1)
		{
			printf("input your expression:");
			scanf("%s",buf);
			getchar();
			printf("the answer is:");
			if(expressionevaluation(ques,answ)==1) 
				printf("%.3f\n",*answ);
			else
				printf("error.\n");
			if(getchar()=='\n')
				continue;
			else
				break;
		}
	}
	free(answ);
}

SQSTACKP initstack(SQSTACKP sqstack)//initialise
{
	sqstack=(SQSTACKP)malloc(sizeof(SQSTACK));
	if(!sqstack) return NULL;
	(*sqstack).base=(ELEMTYPE*)malloc(DEFSIZE*sizeof(ELEMTYPE)+1);//one more nod as final,avoid wild pointer
	if(!(*sqstack).base) return NULL;
	(*sqstack).top=(*sqstack).base;
	(*sqstack).stackSize=DEFSIZE;
	return sqstack;
}//initstack

int isfull(SQSTACKP sqstack)//full return 1,not full return -1
{
	if((*sqstack).top==((*sqstack).base+(*sqstack).stackSize)) return 1;//full condition
	return -1;
}//isfull

int isempty(SQSTACKP sqstack)//empty return 1,not empty return -1
{
	if((*sqstack).base==(*sqstack).top) return 1;
	return -1;
}//isempty

int push(SQSTACKP sqstack,ELEMTYPE elem)//success return 1,fail return -1
{
	if(isfull(sqstack)==1)
		if(addroom(sqstack,5)==-1) return -1;
	*(*sqstack).top++=elem;
	return 1;
}//push

ELEMTYPE* pop(SQSTACKP sqstack)
{
	if(isempty(sqstack)==1) 
		return NULL;//error
	return --(*sqstack).top;
}//pop

ELEMTYPE* gettop(SQSTACKP sqstack)
{
	if(isempty(sqstack)==1) 
		return NULL;
	return ((*sqstack).top-1);
}//gettop

int addroom(SQSTACKP sqstack,int howmuch)
{
	void *temp;
	if((*sqstack).stackSize>=1000) return -1;//too much memory is not allowed
	temp=(ELEMTYPE*)realloc((*sqstack).base,sizeof(ELEMTYPE)*((*sqstack).stackSize+howmuch+1));
	if(!temp) return -1;
	(*sqstack).base=temp;
	(*sqstack).stackSize=(*sqstack).stackSize+howmuch;
	return 1;
}//addroom

int oprpriority(int ch,int top) //new-top
{
	if(ch==-1 || top==-1) 
		return -1;//parameter error
	switch(top)
	{
	case 43:if(ch==42||ch==47||ch==40) 
				return 62;
			else 
				return 60;
			break;
	case 45:if(ch==42||ch==47||ch==40) 
				return 62;
			else 
				return 60;
			break;
	case 42:if(ch==40) return 62;
			else 
				return 60;
			break;
	case 47:if(ch==40) return 62;
			else 
				return 60;
			break;
	case 40:if(ch==41) return 61;
			else 
				if(ch==35) 
					return -1;
				else 
					return 62;
			break;
	case 41:if(ch==40) 
				return -1;
			else 
				return 60;
			break;
	case 35:if(ch==35) 
				return 61;
			else 
				if(ch==41) 
					return -1;
				else 
					return 62;
			break;
	default:return -1;
	}
}

int oprchange(char *ch)
{
	switch(*ch)
	{
	case '+':return 43;break;
	case '-':return 45;break;
	case '*':return 42;break;
	case '/':return 47;break;
	case '#':return 35;break;
	case '(':return 40;break;
	case ')':return 41;break;
	default:return -1;
	}
}

char* numjudge(SQSTACKP sqstack,char *ch)//return remaining strings
{
	double sum=0,floa=0;
	int temp=0;
	while(*ch>='0' && *ch<='9')
		sum=sum*10+(*ch++)-'0';
	if((*ch)=='.')
	{
		ch++;
		while(*ch>='0' && *ch<='9')
		{
			floa=floa*10+(*ch++)-'0';
			temp++;
		}
		while(temp--)
			floa=floa/10;
	}
	push(sqstack,sum+floa);
	return ch;
}

int calculation(SQSTACKP sqstack,double *left,int opr,double *right)
{
	if(opr==-1 || sqstack==NULL || right==NULL || left==NULL) return -1;
	switch(opr)
	{
	case 43:if(push(sqstack,*left + *right)==1) 
				return 1;
			else 
				return -1;
			break;
	case 45:if(push(sqstack,*left - *right)==1) 
				return 1;
			else 
				return -1;
			break;
	case 42:if(push(sqstack,*left * *right)==1) 
				return 1;
			else 
				return -1;
			break;
	case 47:if(push(sqstack,*left / *right)==1) 
				return 1;
			else 
				return -1;
			break;
	default:return -1;
	}
}

int expressionevaluation(char *ques,double *answ)//operand 操作数,operator 运算符
{
	SQSTACKP opd=NULL,opr=NULL;
	opd=initstack(opd);
	opr=initstack(opr);
	if(push(opr,35)==-1) 
	{
		free(opd);
		free(opr);
		return -1;//'#' is 35
	}
	while(*ques)
	{
		if(*ques>='0' && *ques <='9')
			ques=numjudge(opd,ques);
		else
		{
			switch(oprpriority(oprchange(ques),(int)*gettop(opr)))//new-top
			{
			case 62:push(opr,oprchange(ques));break;//'>'
			case 60:if(calculation(opd,pop(opd),(int)*pop(opr),pop(opd))==-1) 
					{
						free(opd);
						free(opr);
						return -1;
					}
					else
						continue;
					break;//'<'
			case 61:if(*ques==')') 
						pop(opr);
					else 
					{	
						if(isempty(opd)==1)
						{
							free(opd);
							free(opr);
							return -1;
						}
						*answ=*pop(opd);
						free(opd);
						free(opr);
						return 1;
					}
					break;
			default:free(opd);free(opr);return -1;
			}
			ques++;
		}
	}
	free(opd);
	free(opr);
	return -1;
}

请留下您的宝贵意见!!!

请留下您的宝贵意见!!!

请留下您的宝贵意见!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值