c语言版数据结构(奇迹冬瓜)-栈实战(4)表达式求值

本文介绍了一个使用C语言实现的表达式求值程序。该程序通过两个栈分别存储字符运算符和整数,实现了基本的四则运算,并考虑了括号的影响。文章详细展示了程序的实现过程和核心算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

//c语言版数据结构(奇迹冬瓜)-栈实战(4)表达式求值

/*
这个算法难的不是思想,而是尽可能的解决输入格式的问题
这个程序还有两个问题没有解决可以实现输出负数,但是不能输入负数,一旦输入时括号不匹配会发生错误。
主要思想:
利用两个栈,一个存放字符运算符,一个来存放整数.
其中涉及整数的转换和表达式的格式检测及算符之间的优先级.
本算法还很不工整优化.
*/

//-----头文件------

#include<stdio.h>
#include<stdlib.h>

//-----宏定义------

#define INIT_STACKSIZE 100
#define INCREMENTSIZE 10
#define TRUE 1
#define ERROR 0
#define OVERFLOW -2

//-----替换和结构体-----

typedef int Bool;
typedef struct
{
	char *Base,*Top;
	int stacksize;
}SqStackC,*StackC;
typedef struct
{
	int *Base,*Top;
	int stacksize;
}SqStackI,*StackI;

//-------函数列表-------

Bool InitStackC(StackC s);
Bool PopC(StackC s,char *e);
Bool PushC(StackC s,char e);
Bool StackEmptyC(StackC s);
Bool ClearStackC(StackC s);
char GetTopC(StackC s);

Bool InitStackI(StackI s);
Bool PopI(StackI s,int *e);
Bool PushI(StackI s,int e);
Bool StackEmptyI(StackI s);
Bool ClearStackI(StackI s);
int GetTopI(StackI s);

Bool InN(char ch);
void Expression();
Bool Rule(char ch);
char Precede(char c1,char c2);
int Operate(int a,char theta,int b);

//------主函数------

void main()
{
	Expression();
}

//-----其余函数------

void Expression()
{
	SqStackC sq1,*OPTR=&sq1;
	SqStackI sq2,*OPND=&sq2;
	int integer=0,ei,i,flag,startflag,flag1,flag2,flag3,a,b;
	char ec,ch,theta;
	do
	{   flag3=0;
	flag=1;
	flag1=0;
	flag2=0;
	startflag=0;
	InitStackC(OPTR);InitStackI(OPND);
	PushC(OPTR,'#');
	ch=getchar();
	while('#'!=ch||'#'!=GetTopC(OPTR))
	{

		if(!Rule(ch)||(0==startflag&&('+'==ch||'*'==ch||'/'==ch||'-'==ch))||flag1>=2)
		{
			flag=0;
		}
		if(InN(ch))
		{
			flag1=0;
			if(0==integer&&'0'==ch)
			{
				flag=0;
			}
			integer=integer*10+ch-'0';
		}
		else if(('+'==ch||'-'==ch||'*'==ch||'/'==ch||'#'==ch||')'==ch)&&(0==flag2)&&(0!=integer&&'0'!=ch))
		{
			flag1++;
			PushI(OPND,integer);
			integer=0;
		}
		if(Rule(ch)&&(!InN(ch)))
		{
			switch(Precede(GetTopC(OPTR),ch))
			{
			case '<':PushC(OPTR,ch);ch=getchar();flag2=0;break;
			case '=':PopC(OPTR,&ec);ch=getchar();flag2=0;break;
			case '>':PopI(OPND,&b);PopI(OPND,&a);PopC(OPTR,&theta);PushI(OPND,Operate(a,theta,b));flag2=1;break;
			case '@':flag=0;break;
			}
		}
		else
		{
			ch=getchar();
			flag2=0;
		}
		startflag=1;
		flag3++;
		if(flag3>30)
		{
			flag=0;
		}
	}
	if(0==flag)
	{
		printf("表达式格式错误!重新输入.\n");
		getchar();
		ClearStackC(OPTR);
		ClearStackI(OPND);
	}
	}while(0==flag);
	while(!StackEmptyI(OPND))
	{
		PopI(OPND,&ei);
		printf("%d ",ei);
	}
	getchar();
	getchar();
}

Bool InitStackC(StackC s)
{
	if(!(s->Base=(char*)malloc(INIT_STACKSIZE*sizeof(char))))
	{
		exit(OVERFLOW);
	}
	s->Top=s->Base;
	s->stacksize=INIT_STACKSIZE;
	return TRUE;
}

Bool PopC(StackC s,char *e)
{
	if(s->Base==s->Top)
	{
		return ERROR;
	}
	*e=*(--s->Top);
	return TRUE;
}

Bool PushC(StackC s,char e)
{
	if(s->Top-s->Base>=s->stacksize)
	{
		if(!(s->Base=(char*)realloc(s->Base,(INIT_STACKSIZE+INCREMENTSIZE)*sizeof(char))))
		{
			exit(OVERFLOW);
		}
		s->Top=s->Base+s->stacksize;
		s->stacksize+=INIT_STACKSIZE;
	}
	*(s->Top++)=e;
	return TRUE;
}

Bool StackEmptyC(StackC s)
{
	return s->Base==s->Top?TRUE:ERROR;
}

Bool ClearStackC(StackC s)
{
	free(s->Base);
	s->Base=NULL;
	s->Top=NULL;
	return TRUE;
}

char GetTopC(StackC s)
{
	if(!s->stacksize||s->Base==s->Top)
	{
		return ERROR;
	}
	return *(s->Top-1);
}

Bool InitStackI(StackI s)
{
	if(!(s->Base=(int*)malloc(INIT_STACKSIZE*sizeof(int))))
	{
		exit(OVERFLOW);
	}
	s->Top=s->Base;
	s->stacksize=INIT_STACKSIZE;
	return TRUE;
}

Bool PopI(StackI s,int *e)
{
	if(s->Base==s->Top)
	{
		return ERROR;
	}
	*e=*(--s->Top);
	return TRUE;
}

Bool PushI(StackI s,int e)
{
	if(s->Top-s->Base>=s->stacksize)
	{
		if(!(s->Base=(int*)realloc(s->Base,(INIT_STACKSIZE+INCREMENTSIZE)*sizeof(int))))
		{
			exit(OVERFLOW);
		}
		s->Top=s->Base+s->stacksize;
		s->stacksize+=INIT_STACKSIZE;
	}
	*(s->Top++)=e;
	return TRUE;
}

Bool StackEmptyI(StackI s)
{
	return s->Base==s->Top?TRUE:ERROR;
}

Bool ClearStackI(StackI s)
{
	free(s->Base);
	s->Top=s->Base=NULL;
	return TRUE;
}

int GetTopI(StackI s)
{
	if(!s->stacksize||s->Base==s->Top)
	{
		return ERROR;
	}
	return *(s->Top-1);
}

Bool InN(char ch)
{
	return ch>='0'&&ch<='9'?TRUE:ERROR;
}

Bool Rule(char ch)
{
	if(ch>='0'&&ch<='9')
	{
		return TRUE;
	}
	else if('#'==ch||'('==ch||')'==ch||'+'==ch||'-'==ch||'*'==ch||'/'==ch)
	{
		return TRUE;
	}
	return ERROR;
}

char Precede(char c2,char c1)
{
	char opera[8][8]={
		{'@','+','-','*','/','(',')','#'},
		{'+','>','>','<','<','<','>','>'},
		{'-','>','>','<','<','<','>','>'},
		{'*','>','>','>','>','<','>','>'},
		{'/','>','>','>','>','<','>','>'},
		{'(','<','<','<','<','<','=','@'},
		{')','>','>','>','>','@','>','>'},
		{'#','<','<','<','<','<','@','='}};
	int i,j,mark_i=0,mark_j=0;
	for(i=0;i<8;i++)
	{
		if(opera[0][i]==c2)
		{
			mark_i=i;
		}
	}
	for(j=0;j<8;j++)
	{
		if(opera[j][0]==c1)
		{
			mark_j=j;
		}
	}
	return opera[mark_i][mark_j];
}

int Operate(int a,char theta,int b)
{
	int res=0;
	switch(theta)
	{
	    case '+':res=a+b;break;
		case '-':res=a-b;break;
		case '*':res=a*b;break;
		case '/':res=a/b;break;
	}
	return res;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值