HDU 1237(简单计算器)栈的应用-表达式求值

直接拿前面栈的表达式改的,把INT改成DOUBLE就行了,忘记删掉输出的那句话了,莫名其妙的错了好多,这就是ACM,输出不像书本,有那么多冗余的句子。

只是为了练习栈的应用,此题还有其它比较简洁的方法。

代码:

#include<stdio.h>
#include<string.h>
#include<malloc.h>

#define InitStackSize 210
#define Increase 100


typedef struct SqcharStack
{
	char *base,*top;
	int stacksize;	
}SqcharStack;

typedef struct SqdoubleStack
{
	double *base,*top;
	int stacksize;
}SqdoubleStack;

void InitcharStack(SqcharStack &s)
{
	s.base=s.top=(char*)malloc(InitStackSize*sizeof(char));
	s.stacksize=InitStackSize;
}

void InitdoubleStack(SqdoubleStack &s)
{
	s.base=s.top=(double*)malloc(InitStackSize*sizeof(double));
	s.stacksize=InitStackSize;
} 

void PushcharStack(SqcharStack &s,char key)  //字符栈 
{
	if(s.top-s.base>=s.stacksize)
	{
		s.base=(char*)realloc(s.base,(s.stacksize+Increase)*sizeof(char));
		s.top=s.base+s.stacksize;
		s.stacksize+=Increase;
	}
	*s.top=key;
	s.top++;
}

void PushdoubleStack(SqdoubleStack &s,double key) //数字栈 
{
	if(s.top-s.base>=s.stacksize)
	{
		s.base=(double*)realloc(s.base,(Increase+s.stacksize)*sizeof(double));
		s.top=s.base+s.stacksize;
		s.stacksize+=Increase;
	}
	*s.top=key;
	s.top++;
}

char GetcharStackTop(SqcharStack S)
{
	char e;
	e=*--S.top;
	return e;
}

double GetdoubleStackTop(SqdoubleStack S)
{
	double e;
	e=*--S.top;
	return e;
}

int In(char a,char sym[])
{
	int i;
	for(i=0;i<7;i++)
		if(sym[i]==a) return 1;	
	return 0;
}

void PopcharStack(SqcharStack &s)
{
	s.top--;
}

void PopdoubleStack(SqdoubleStack &s)
{
	s.top--;
}


char Precede(char a,char b,char pr[][10])  //判断优先级 
{
	int i,j;
	switch(a)
	{
		case '+':i=0;break;
		case '-':i=1;break;
		case '*':i=2;break;
		case '/':i=3;break;
		case '(':i=4;break;
		case ')':i=5;break;
		case '=':i=6;break;
		default:break;
	}
	switch(b)
	{
		case '+':j=0;break;
		case '-':j=1;break;
		case '*':j=2;break;
		case '/':j=3;break;
		case '(':j=4;break;
		case ')':j=5;break;
		case '=':j=6;break;
		default:break;
	}
	return pr[i][j];
}

double Operate(double a,double b,char ch)
{
	switch(ch)
	{
		case '+':return b+a;break;
		case '-':return b-a;break;
		case '*':return b*a;break;
		case '/':return b/a;break;
		default:break;
	}
}

int main()
{
	SqcharStack OPTR;
	SqdoubleStack OPND;
	char str[211];
	int i,k,j,byt,temp,len;
	double num;
	double a,b; 
	char theta;
	char pre[][10]={
	{'>','>','<','<','<','>','>'},
	{'>','>','<','<','<','>','>'},
	{'>','>','>','>','<','>','>'},
	{'>','>','>','>','<','>','>'},
	{'<','<','<','<','<','=','0'},
	{'>','>','>','>','0','>','>'},
	{'<','<','<','<','<','0','='}};  //优先级表   
	char OP[]={'+','-','*','/','(',')','='};  //操作符集合 
	
	memset(str,'\0',sizeof(str));
	while(gets(str) && strcmp(str,"0")!=0)
	{
		InitcharStack(OPTR);
		InitdoubleStack(OPND);
		PushcharStack(OPTR,'=');
		len=strlen(str);
		str[len]='=';
		len++;
		i=0;
		while(i<len)
		{
			if(str[i]==' ')
			{
				i++;
				continue;
			} 
			if(!In(str[i],OP))   //如果不是操作符,读入数字 
			{
				SqcharStack Num;
				InitcharStack(Num);
				byt=0; //数字位数 
				//读入数字字符
				for(j=i;!In(str[j],OP) && str[j]!=' ' && str[j]!='\0' && str[j]!='=';j++)
				{
					PushcharStack(Num,str[j]);
					byt++;
				}
				num=0;//生成数字 
				temp=1;
				while(byt--)
				{
					k=(GetcharStackTop(Num)-'0');
					num+=temp*k;
					temp*=10;
					PopcharStack(Num);
				}
				PushdoubleStack(OPND,num);
				//while 生成数字
				i=j; //i位置跳过数字	
			}//if 是数字 
			else//操作符 
			{
				switch(Precede(GetcharStackTop(OPTR),str[i],pre))
				{
					case '<':PushcharStack(OPTR,str[i]);i++;break; //栈顶元素优先权低 
					case '=':PopcharStack(OPTR);i++;break;//脱括号 
					case '>':
					theta=GetcharStackTop(OPTR); //取得栈中运算符 
					PopcharStack(OPTR);
					a=GetdoubleStackTop(OPND);
					PopdoubleStack(OPND);
					b=GetdoubleStackTop(OPND);
					PopdoubleStack(OPND);
					PushdoubleStack(OPND,Operate(a,b,theta)); //这里注意a,b顺序,反了的话减和除运算就错了 
					break;
				}
				
			} 
		}
		printf("%.2lf\n",GetdoubleStackTop(OPND));
		memset(str,'\0',sizeof(str));
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值