栈的应用-表达式求值-数据结构

栈的应用之一,表达式求值,严慧敏书上给的例子是只有1位数的输入,这里稍微改下,处理下多位数的+、-、*、/。

表达式要求输入合法,且除数要能整除,不然就int掉,算出来错了,主要就是书中优先级表的应用。

省去那些STATUS的返回,什么ERROR  OK  OVERFLOW 的。

完整代码:

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

#define InitStackSize 100
#define Increase 100


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

typedef struct SqintStack
{
	int *base,*top;
	int stacksize;
}SqintStack;

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

void InitintStack(SqintStack &s)
{
	s.base=s.top=(int*)malloc(InitStackSize*sizeof(int));
	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 PushintStack(SqintStack &s,int key) //数字栈 
{
	if(s.top-s.base>=s.stacksize)
	{
		s.base=(int*)realloc(s.base,(Increase+s.stacksize)*sizeof(int));
		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;
}

int GetintStackTop(SqintStack S)
{
	int 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 PopintStack(SqintStack &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];
}

int Operate(int a,int 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;
	SqintStack OPND;
	char str[101];
	int i,k,j,byt,num,temp,len;
	int a,b; 
	char theta;
	char pre[][10]={
	{'>','>','<','<','<','>','>'},
	{'>','>','<','<','<','>','>'},
	{'>','>','>','>','<','>','>'},
	{'>','>','>','>','<','>','>'},
	{'<','<','<','<','<','=','0'},
	{'>','>','>','>','0','>','>'},
	{'<','<','<','<','<','0','='}};  //优先级表   
	char OP[]={'+','-','*','/','(',')','='};  //操作符集合 
	InitcharStack(OPTR);
	InitintStack(OPND);
	memset(str,'\0',sizeof(str));
	while(gets(str))
	{
		PushcharStack(OPTR,'=');
		len=strlen(str);
		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);
				}
				PushintStack(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=GetintStackTop(OPND);
					PopintStack(OPND);
					b=GetintStackTop(OPND);
					PopintStack(OPND);
					PushintStack(OPND,Operate(a,b,theta)); //这里注意a,b顺序,反了的话减和除运算就错了 
					break;
				}
				
			} 
		}//while( || )
		printf("The result is:%d\n",GetintStackTop(OPND));
	}
	return 0;
}

/*
123+456=

4+5*6-10=

(2+8)*6/5=

100/2/2/5= 
*/



  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值