栈求表达式的值
思路
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]);
}
测试结果