思路
建立操作数栈和运算符栈。运算符有优先级。规则:
自左至右扫描表达式,凡是遇到操作数一律进操作数栈。
当遇到运算符时,如果它的优先级比运算符栈栈顶元素的优先级高就进栈。
反之,取出栈顶运算符和操作数栈栈顶的连续两个操作数进行运算,并将结果存入操作数栈,
然后继续比较该运算符与栈顶运算符的优先级。
左括号一律进运算符栈,右括号一律不进运算符栈,取出运算符栈顶运算符和操作数栈顶的两个操作数进行运算,
并将结果压入操作数栈,直到取出左括号为止。
链式实现文件
头文件
#ifndef _STACK_H_
#define _STACK_H_
typedef enum{FALSE,TRUE} BOOL;
typedef int Data;
typedef struct _node
{
Data data; //节点数据
struct _node *next ; //
}Node;
typedef struct _stack
{
Node *top;
}Stack;
//初始化空栈
void Init_Stack(Stack*s);
//入栈
void Push(Stack*s,Data data);
//判断空栈
BOOL IsEmpty(Stack*s);
//出栈
void Pop(Stack*s);
//获取栈顶元素
Data Gettop(Stack*s);
//打印栈数据
void Display_Stack(Stack*s);
#endif//_STATCK_H_
C文件
#include "stack.h"
#include <stdlib.h>
#include <stdio.h>
void Init_Stack(Stack*s)
{
if(NULL == s)
return ;
s->top = NULL;
}
void Push(Stack*s,Data data)
{
if(NULL == s)
return ;
Node *new_node =(Node*)malloc(sizeof(Node)/sizeof(char));
if(NULL == new_node)
{
return ;
}
new_node->data = data;
new_node->next = s->top;
s->top= new_node;
}
BOOL IsEmpty(Stack*s)
{
if(NULL == s)
return ;
if(NULL == s->top)
return TRUE;
return FALSE;
}
void Pop(Stack*s)
{
if(NULL == s)
return ;
if(IsEmpty(s) == TRUE)
return ;
Node *tmp = s->top;
s->top = tmp->next;
free(tmp);
}
Data Gettop(Stack*s)
{
if(NULL == s)
return ;
if(IsEmpty(s) == TRUE)
{
printf("栈空\n");
exit(-1) ;
}
return s->top->data;
}
void Display_Stack(Stack*s)
{
while(!IsEmpty(s))
{
printf("%d\n",Gettop(s));
Pop(s);
}
printf("栈打印结束并置空栈!!!!");
}
计算器实现文件
头文件
#ifndef _CALCULATOR_H_
#define _CALCULATOR_H_
/************** 函数名:IsPush **********************
函数功能:
判断操作符是否入栈
函数参数:
[in] s_opes : 操作符栈
[in] p : 需要判断的操作符
函数返回值:
TRUE : 入栈
FALSE : 不入栈
*************** 函数名:IsPush *********************/
BOOL IsPush(Stack *s_opes,char*p);
/************** 函数名:calcu **********************
函数功能:
在操作数栈取出两个操作数 ,
在操作符栈取出一个操作符 ,
进行计算。
函数参数:
[in] s_opes : 操作符栈
[in] s_nums : 操作数栈
函数返回值:
*************** 函数名:calcu *********************/
void calcu(Stack *s_opes,Stack *s_nums);
/************** 函数名:deal_ope **********************
函数功能:
操作符处理。
如果不能入栈进行计算,一直计算操作符栈为空。
如果能入栈,则入栈。
函数参数:
[in] s_opes : 操作符栈
[in] s_nums : 操作数栈
[in] p : 需要入栈的操作符
函数返回值:
*************** 函数名:deal_ope *********************/
void deal_ope(Stack *s_nums,Stack *s_opes,char*p);
/************** 函数名:Calculator **********************
函数功能:
计算加减乘除含括号的多项式运算
函数参数:
[in]exp : 需要计算的合法表达式
函数返回值:
返回类型 :int
返回值 :计算的结果
*************** 函数名:Calculator*********************/
int Calculator(char*exp);
#endif//_CALCULATOR_H_
C文件
#include "stdio.h"
#include "stack.h"
#include "calculator.h"
// 判断操作符是否入栈
BOOL IsPush(Stack *s_opes,char*p)
{
if(IsEmpty(s_opes))
return TRUE;
int top_data = Gettop(s_opes);
switch (top_data)
{
case '+':
case '-':
if(*p == '*' || *p == '/' || *p == '(')
return TRUE;
else
return FALSE;
break;
case '*':
case '/':
if( *p == '(')
return TRUE;
else
return FALSE;
break;
case '(':
if( *p == ')')
{
Pop(s_opes);
return TRUE;
}
break;
default :
break;
}
}
// 计算
void calcu(Stack *s_opes,Stack *s_nums)
{
if(s_opes == NULL || s_nums == NULL)
return;
if(IsEmpty(s_opes))
return ;
int res;
int num1 = Gettop(s_nums);
Pop(s_nums);
int num2 = Gettop(s_nums);
Pop(s_nums);
int ope = Gettop(s_opes);
switch (ope)
{
case '+':
res = num2 + num1;
break;
case '-':
res = num2 - num1;
break;
case '*':
res = num2 * num1;
break;
case '/':
res = num2 / num1;
break;
default:
break;
}
Push(s_nums,res);
Pop(s_opes);
}
//操作符处理
void deal_ope(Stack *s_nums,Stack *s_opes,char*p)
{
// 操作符不入栈计算
while(IsPush(s_opes,p) == FALSE)
{
calcu(s_opes,s_nums);
}
// 操作符入栈
if(IsPush(s_opes,p) == TRUE)
{
if( *p == ')')
return ;
Push(s_opes,*p);
}
}
int Calculator(char*exp)
{
Stack s_nums; //操作数栈
Stack s_opes; //操作符栈
Init_Stack(&s_nums);
Init_Stack(&s_opes);
char *p = exp;
//入栈
while(*p)
{
// 操作数入栈
if(*p >= '0' && *p <= '9')
{
int num = 0;
while( *p >= '0' && *p <= '9')
{
num = num*10 + (*p -'0');
p++;
}
Push(&s_nums,num);
}
else // 操作符入栈
{
OpesPush(&s_nums,&s_opes,p);
p++;
}
}
calcu(&s_opes,&s_nums); //计算最终的值
int res = Gettop(&s_nums);
//剩余元素出栈
Pop(&s_nums);
return res;
}