栈求表达式的值(完整代码),带括号版;包括栈的基本操作

栈求表达式的值

思路
1.操作数直接进
2.符号栈为空时,直接进
3.优先级高,进栈
4.遇到‘(’,进栈
5.遇到‘)’,循环出栈
可输入‘+’,‘-’,‘*’,‘/’,‘%’,‘(’,‘)’几种符号;

main.c

#include"biaodashi.h"

int main()
{
	char str[128];
	scanf("%s",str);
	GetValue(str);
	return 0;
}

biaodashi.h

#ifndef __biaodashi_H__
#define __biaodashi_H__

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


//需要栈的节点
typedef struct node
{
	char data;
	struct node * next;
}node;

//需要一个管理栈的头结点
typedef struct 
{
	int num;//统计栈里面元素的个数的东西
	node * top;//栈顶
	node * bottom;//栈底
}stack;

//InitStack 初始化一个栈
//将这个头节点返回
stack *InitStack(void);
//DestroyStack 销毁一个栈
void  DestroyStack(stack * head);
//ClearStack 清空一个栈
void  ClearStack(stack * head);
//checkStackEmpty 检查一个栈是否为空
//为空返回true        不为空返回false
bool  checkStackEmpty(stack * head);
//GetTop 获取栈顶的元素节点 但是不会出栈
//失败返回-1
void  GetTop(stack * head,char *e);
//Push 入栈	
//相当于尾插法
void  Push(stack * head,char data);
//Pop 出栈
bool Pop(stack * head,char *e);

void GetValue(char *str);//求表达式的值
int grade(char g);//判断优先级

#endif

biaodashi.h

#include"biaodashi.h"

#define ture true
#define flase false


//InitStack 初始化一个栈
//将这个头节点返回
stack *InitStack(void)
{
	stack * head = malloc(sizeof(*head));
	head ->num = 0;
	head ->top = head ->bottom = NULL;
	return head;
}

//checkStackEmpty 检查一个栈是否为空
//为空返回true        不为空返回false
bool checkStackEmpty(stack * head)
{
	if(head ->num)//num有   表示这个栈里面有元素            就不是空的
	{
		return false;

	}
	return true;
}

//GetTop 获取栈顶的元素节 但是不会出栈
//失败返回-1
void  GetTop(stack * head,char *e)
{
	if(head ->num==0)
	{
		return;
	}
	*e = head ->top ->data;
}

//Push 入栈	
//相当于尾插法
void  Push(stack * head,char data)
{
	//head是否为空
	if(!head)
	{
		printf("请初始化栈\n");
		return;
	}
	node * pnew = malloc(sizeof(*pnew));
	pnew  ->data = data;
	pnew ->next = NULL;
	if(!(head ->top))//这个栈是空栈
	{
		head ->bottom = head ->top = pnew;
		head ->num++;
		return;
	}
	//尾插法插入节点
	pnew ->next  = head ->top;
	head  ->top = pnew;
	head  ->num++;	
}

//Pop 出栈
bool Pop(stack * head,char *e)
{
	if(!head)//如果这个头部为空
	{
		printf("头部都为空了\n");
		return false;
	}
	if(checkStackEmpty(head))
	{
		printf("空栈\n");
		return false;
	}
	*e=head ->top  ->data;
	//出栈       摘头 
	node *p = head ->top;
	head  ->top = head ->top ->next;
	p  ->next = NULL;
	free(p);
	head  ->num--;
	return true;
}
//获得优先级
int grade(char g)
{
	if(g=='+'||g=='-')
	{
		return 1;
	}
	if(g=='*'||g=='/'||g=='%')
	{
		return 2;
	}
	if(g=='('||g==')')
	{
		return 3;
	}
}
//计算值
void GetValue(char *str)
{
	stack * headf = InitStack();
	//stack * headv = InitStack();
	int num[128];//
	int k = 0;//
	int num1,num2;//
	char ch;
	int temp;
	int flag = 1;
	if(*str == '-')//第一个数为负数
	{
		flag = -1;
		str++;
	}
	while(*str != '\0')
	{
		if(!((*str >= '0' && *str <= '9') ||*str == '+' || *str == '-' || *str == '*' || *str == '%' || *str == '/' || *str == '(' || *str == ')'))//输入错误的表达式
		{
			printf("表达式错误\n");
			return;
		}
		if(*str >= '0' && *str <= '9')//数字直接存入
		{
			temp = 0;
			while(*str >= '0' && *str <= '9')
			{
				temp = *str - '0' + temp *10;//将字符转换成整形
				str++;
			}
			num[k++]=temp * flag;
			flag = 1;
			continue;
		}
		if(headf->num == 0)//符号栈没有元素直接存入
		{
			Push(headf,*str);
			str++;
			continue;
		}
		if(*str == '+' || *str == '-' || *str == '*' || *str == '%' || *str == '/' || *str == '(' || *str == ')')
		{
			GetTop(headf,&ch);
			if((grade(ch)<grade(*str) && *str != ')') || ch == '(')//判断优先级,优先级高或符号栈顶元素为‘(’直接存入
			{
				Push(headf,*str);
				str++;
				if(*str == '-')//针对括号后的第一个数为负的情况
				{
					flag=-1;
					str++;
				}
				continue;
			}
			else
			{
				num1 = num[--k];
				num2 = num[--k];
				switch(ch)//进行运算
				{
					case '+': num[k++] = num2 + num1;break;
					case '-': num[k++] = num2 - num1;break;
					case '*': num[k++] = num2 * num1;break;
					case '/': num[k++] = num2 / num1;break;
					case '%': num[k++] = num2 % num1;break;
				}
				Pop(headf,&ch);
				if(*str == ')')//如果表达式元素为‘)’,循环出栈
				{
					str++;
					GetTop(headf,&ch);
					if(ch == '(')
					{
						Pop(headf,&ch);
					}
					while(ch!='(')//计算括号内的值
					{
						Pop(headf,&ch);
						if(ch == '(')
						{
							break;
						}
						num1 = num[--k];
						num2 = num[--k];
						switch(ch)
							{
								case '+': num[k++] = num2 + num1;break;
								case '-': num[k++] = num2 - num1;break;
								case '*': num[k++] = num2 * num1;break;
								case '/': num[k++] = num2 / num1;break;
								case '%': num[k++] = num2 % num1;break;
							}	
					}
					continue;
				}
				if(headf->num != 0)//特殊情况
				{
					GetTop(headf,&ch);
				}
				if(headf->num != 0 && ch == '-' && (grade(ch) >= grade(*str)))//先减后加
				{
					Pop(headf,&ch);
					num1 = num[--k];
					num2 = num[--k];
					num[k++] = num2 - num1;
					Push(headf,*str);
					str++;
				}
				else
				{
					Push(headf,*str);
					str++;
				}
			}
		}
	}
	while(headf->num)//表达式为空,但是符号栈不为空
	{
		num1 = num[--k];
		num2 = num[--k];
		Pop(headf,&ch);
		switch(ch)
			{
				case '+': num[k++] = num2 + num1;break;
				case '-': num[k++] = num2 - num1;break;
				case '*': num[k++] = num2 * num1;break;
				case '/': num[k++] = num2 / num1;break;
				case '%': num[k++] = num2 % num1;break;
			}	
	}
	printf("value = %d\n",num[0]);
}


测试结果
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值