n栈在表达式计算过程中的应用 :建立操作数栈和运算符栈。运算符有优先级。规则:
n自左至右扫描表达式,凡是遇到操作数一律进操作数栈。
n当遇到运算符时,如果它的优先级比运算符栈栈顶元素的优先级高就进栈。反之,取出栈顶运算符和操作数栈栈顶的连续两个操作数进行运算,并将结果存入操作数栈,然后继续比较该运算符与栈顶运算符的优先级。
n左括号一律进运算符栈,右括号一律不进运算符栈,取出运算符栈顶运算符和操作数栈顶的两个操作数进行运算,并将结果压入操作数栈,直到取出左括号为止。
#include "calculator.h"
#include <stdio.h>
int main()
{
LinkStack *s = Create_Stack();
char str[100];
int i = 0;
char *pstr = str;
char *pnum = str;
printf("Please input an expression:");
fgets(str,100,stdin);
while(str[i])
{
if(str[i] == '\n')
{
str[i] = '\0';
break;
}
i++;
}
int tmp = 0;
while(*pstr)
{
if(*pstr >= 'a' && *pstr <= 'z' ||\
*pstr >= 'A' && *pstr <= 'Z')
{
tmp = 1;
}
pstr++;
}
if(tmp == 1)
{
errno = INPUT_ERROR;
myError("输入错误");
return FALSE;
}
pstr = str;
int flag = 0;
while(*pstr)
{
if(*pstr >= '0' && *pstr <= '9')
{
flag = 1;
pstr++;
continue;
}
else
{
if(flag == 1)
{
numPush(s,atoi(pnum));
flag = 0;
}
if(*pstr == '(')
{
opPush(s,*pstr);
}
else if(*pstr == ')')
{
while(operate(s));
}
else
{
while(cmp_op(s,*pstr) != TRUE)
{
operate(s);
}
opPush(s,*pstr);
}
pnum = pstr + 1;
}
pstr++;
}
if(flag == 1)
{
numPush(s,atoi(pnum));
}
while(operate(s));
int result;
numPop(s,&result);
printf("result = %d\n",result);
return 0;
}
#ifndef __CALCULATOR_H__
#define __CALCULATOR_H__
#include "error.h"
#define TRUE 1
#define FALSE 0
typedef int num;
typedef char op;
typedef struct _numnode
{
num data;
struct _numnode *next;
}numNode;
typedef struct _opnode
{
op data;
struct _opnode *next;
}opNode;
typedef struct _linkstack
{
numNode *numtop;
opNode *optop;
}LinkStack;
//创建链式栈
LinkStack *Create_Stack();
//判断操作数是不是空栈
int numEmpty(LinkStack *s);
//判断操作符是不是空栈
int opEmpty(LinkStack *s);
//操作数进栈
int numPush(LinkStack *s,num x);
//操作符进栈
int opPush(LinkStack *s,op x);
//操作数出栈
int numPop(LinkStack *s,num *x);
//操作符出栈
int opPop(LinkStack *s,op *x);
//取操作符栈顶元素
int GetopTop(LinkStack *s,op *x);
int cmp_op(LinkStack *s,op op2);
int operate(LinkStack *s);
#endif // __CALCULATOR_H__
#include "calculator.h"
#include <stdlib.h>
LinkStack *Create_Stack()
{
LinkStack *s = (LinkStack *)malloc(sizeof(LinkStack) / sizeof(char));
if(s == NULL)
{
errno = MALLOC_ERROR;
return NULL;
}
s->numtop = NULL;
s->optop = NULL;
return s;
}
int numEmpty(LinkStack *s)//判断num是否空栈
{
if(s ==NULL)
{
errno = ERROR;
return FALSE;
}
return s->numtop == NULL;
}
int opEmpty(LinkStack *s)
{
if(s ==NULL)
{
errno = ERROR;
return FALSE;
}
return s->optop == NULL;
}
int numPush(LinkStack *s,num x)
{
if(s ==NULL)
{
errno = ERROR;
return FALSE;
}
numNode *numnode =(numNode *)malloc(sizeof(numNode) / sizeof(char));
if(numnode == NULL)
{
errno = MALLOC_ERROR;
return FALSE;
}
numnode->data = x;
numnode->next = s->numtop;
s->numtop = numnode;
return TRUE;
}
int opPush(LinkStack *s,op x)
{
if(s ==NULL)
{
errno = ERROR;
return FALSE;
}
opNode *opnode =(opNode *)malloc(sizeof(opNode) / sizeof(char));
if(opnode == NULL)
{
errno = MALLOC_ERROR;
return FALSE;
}
opnode->data = x;
opnode->next = s->optop;
s->optop = opnode;
return TRUE;
}
int numPop(LinkStack *s,num *x)
{
if(s ==NULL)
{
errno = ERROR;
return FALSE;
}
if(numEmpty(s))
{
errno = EMPTY_STACK;
return FALSE;
}
numNode *p = s->numtop;
*x = p->data;
s->numtop = p->next;
free(p);
return TRUE;
}
int opPop(LinkStack *s,op *x)
{
if(s ==NULL)
{
errno = ERROR;
return FALSE;
}
if(opEmpty(s))
{
errno = EMPTY_STACK;
return FALSE;
}
opNode *p = s->optop;
*x = p->data;
s->optop = p->next;
free(p);
return TRUE;
}
int GetopTop(LinkStack *s,op *x)
{
if(s ==NULL)
{
errno = ERROR;
return FALSE;
}
if(opEmpty(s))
{
errno = EMPTY_STACK;
return FALSE;
}
*x = s->optop->data;
return TRUE;
}
int cmp_op(LinkStack *s,op op2)
{
if(s ==NULL)
{
errno = ERROR;
return FALSE;
}
if(opEmpty(s))
{
return TRUE;
}
char op1;
GetopTop(s,&op1);
switch(op1)
{
case '+':
return TRUE;
case '-':
if(op2 == '-' || op2 == '+')
return FALSE;
else
return TRUE;
case '*':
return FALSE;
case '/':
return FALSE;
default:
return TRUE;
}
}
int operate(LinkStack *s)
{
if(s ==NULL)
{
errno = ERROR;
return FALSE;
}
if(opEmpty(s))
{
errno = EMPTY_STACK;
return FALSE;
}
char op1;
opPop(s,&op1);
if(op1 == '(')
{
return FALSE;
}
int num1,num2;
numPop(s,&num1);
numPop(s,&num2);
int result;
switch(op1)
{
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num1 / num2;
break;
default:
result = 0;
break;
}
numPush(s,result);
return TRUE;
}
#ifndef __ERROR_H__
#define __ERROR_H__
#include <stdio.h>
#define ERROR -1
#define EMPTY_STACK -2
#define FULL_STACK -3
#define MALLOC_ERROR -4
#define FULL_QUEUE -5
#define EMPTY_QUEUE -6
#define INPUT_ERROR -7
int errno;
void myError(char *str);
char *myStrError(int num);
#endif //__ERROR_H__
#include "error.h"
void myError(char *str)
{
char *msg = myStrError(errno);
printf("%s:%s\n",str,msg);
}
char* myStrError(int num)
{
switch(errno)
{
case ERROR:
return "输入参数错误";
case FULL_STACK:
return "满栈状态";
case EMPTY_STACK:
return "空栈状态";
case MALLOC_ERROR:
return "空间分配失败";
case FULL_QUEUE:
return "队满";
case EMPTY_QUEUE:
return "队空";
case INPUT_ERROR:
return "输入字母";
}
}