栈的表达式求值

由于栈的表达式求值对我本人来说还是过于晦涩,所以只好转载借鉴一下其他大佬的文章,并通过对比进行学习

#include <stdio.h>		
#include <stdlib.h>		
//构建栈的结构 
typedef struct LinkNode{
	char str;
	LinkNode *next;
}LinkNode, *LinkStack; 

//栈的初始化 
void InitStack(LinkStack &S)
{
	S = NULL;
}

//栈空的判断 
bool EmptyStack(LinkStack S)
{
	if (S == NULL)
		return true;
	else
		return false;
}

//进栈操作;单链表的前插操作 
void InsertStack(LinkStack &S, char str)
{
	LinkNode *p;		//定义一个指针结点; 
	p = (LinkNode *)malloc(sizeof(LinkNode));	//分配空间; 
	p->str = str;		//赋值该节点的str属性值; 
	p->next = S;		
	S = p;				//修改 S 的指向 
}

//出栈操作 
bool DeleteStack(LinkStack &S, char &str)
{
	if (EmptyStack(S))	//栈空报错; 
		return false;
	LinkNode *p = S;	//定义一个指针结点,使其指向要被删除的栈顶结点; 
	str = p->str;		//用str记录要被弹出栈的元素值,并传递出去; 
	S = p->next;		//修改S指针指向的位置; 
	free(p);			//释放要被删除的结点 
	return true;
}

//获取栈顶元素,用str传递栈顶元素; 
bool GetStack(LinkStack S, char &str) 
{
	if (EmptyStack(S))	//栈空报错; 
		return false;
	str = S->str;
	return true;
}

//进行 + - * / 运算,将计算结果用Lnum传递; 
bool Operation(char &Lnum, char Rnum, char operation) 
{
	switch (operation)
	{
		case '+':
			Lnum = Lnum + Rnum;
			break;
		case '-':
			Lnum = Lnum - Rnum;
			break;
		case '*':
			Lnum = Lnum * Rnum;
			break;
		case '/':
			if (Rnum == 0)
			{
				printf("除数不能为0!\n");
				return false;
			}
			Lnum = Lnum / Rnum;
			break;
		default:
			printf("有不合法的运算符!\n");
			return false; 
			break;
	}
	return true;
} 

//比较运算符的顺序;用result传递比较结果; 
bool Compare(char one, char topchar, char &result) 
{
	switch (one)
	{
		case '+':
		case '-':
			if (topchar == '(')
				result = '<';	//'+' '-' 进栈; 
			else
				result = '>';	
			break;
		case '*':
		case '/':
			if (topchar == '*' or topchar == '/')
				result = '>';
			else
				result = '<';	//'*' '/' 进栈; 
			break;
		case '(':
			result = '<';
			break;
		case ')':
			result = '=';
			break;
		default :
			printf("有不合法的运算符!\n"); 
			return false;
			break;
	}
	return true;
}

int main() 
{
	LinkStack Snum, Schar;
	InitStack(Snum);		//初始化操作数栈; 
	InitStack(Schar);		//初始化运算符栈; 
	printf("Function:\n"); 
	printf("栈的应用-----表达式求值\n");
	printf("input what you want to calculator:");
	char *op = (char *)malloc(sizeof(char));	//为指针op分配空间; 
	gets(op);			//赋值;
	char topstr,result;		//记录栈顶符号和比较之后的结果; 
	char Lnum,Rnum;			//记录左,右操作数; 
	while (*op)				//循环指针op,直到找到结束符'\0'结束; 
	{
		//如果此时是操作数,循环判断下一位是否是数字; 
		if (*op >= '0' and *op <= '9')
		{
			char num = 0; 
			//eg:读入数据是19,则从左到右读取:1*10+9; 
			while (*op >= '0' and *op <= '9')
			{
				num = *op - '0' + num * 10;
				*op++;
			}
			InsertStack(Snum,num);		//将操作数入栈; 
			*op--;						//恢复上一个指针指向; 
		}else if (*op == '+' or *op == '-' or *op == '*' or *op == '/' or *op == '(' or *op == ')') 
		{
			//比较操作大小,再考虑是否入栈或者进行计算;
			if (!EmptyStack(Schar))				//栈不为空; 
			{	
				GetStack(Schar, topstr);		//获取栈顶操作符; 
				Compare(*op, topstr, result);
				switch (result) 
				{
					case '>':
						//弹出栈顶操作符,进行运算;
						DeleteStack(Schar,topstr);
						if (!DeleteStack(Snum,Rnum))
						{
							printf("右操作数匹配失败。\n");
							return 1;
						}
						if (!DeleteStack(Snum,Lnum))
						{
							printf("左操作数匹配失败。\n");
							return 1;
						}						
						if (!Operation(Lnum,Rnum,topstr))
							return 1;
						InsertStack(Snum,Lnum);		//将计算后的结果重新放入操作数栈;	
						InsertStack(Schar,*op);		//将操作符放入操作符栈; 
						break;
					case '<':
						InsertStack(Schar, *op);	//将操作符入栈;
						break;
					case '=':
						//弹出栈顶操作符,进行运算,直到找到‘(’;
						GetStack(Schar,topstr);		//读取栈顶操作符; 
						while(topstr != '(') 
						{
							DeleteStack(Schar,topstr);
							if (!DeleteStack(Snum,Rnum))
							{
								printf("右操作数匹配失败。\n");
								return 1;
							}
							if (!DeleteStack(Snum,Lnum))
							{
								printf("左操作数匹配失败。\n");
								return 1;
							}						
							if (!Operation(Lnum,Rnum,topstr))
								return 1;
							InsertStack(Snum,Lnum);		//将计算后的结果重新放入操作数栈;							
							GetStack(Schar,topstr);		//读取栈顶操作符;
						}
						DeleteStack(Schar,topstr);
						break;
				}
			}else{
				//栈空操作符直接进栈; 
				InsertStack(Schar, *op);	//将操作符入栈;
			} 		
		}else if(*op != ' ')				//完善程序的健壮性,不是空格符报错; 
		{
			printf("发现不法符号!退出程序。\n");
			return 1; 
		}	 
		*op++;
	}
	while(!EmptyStack(Schar)) 
	{
		//弹出栈顶操作符,进行运算;
		DeleteStack(Schar,topstr);
		if (!DeleteStack(Snum,Rnum))
		{
			printf("右操作数匹配失败。\n");
			return 1;
		}
		if (!DeleteStack(Snum,Lnum))
		{
			printf("左操作数匹配失败。\n");
			return 1;
		}						
		if (!Operation(Lnum,Rnum,topstr))
			return 1;
		InsertStack(Snum,Lnum);		//将计算后的结果重新放入操作数栈;
	}
	DeleteStack(Snum,topstr);
	printf("%d",topstr);	
	return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值