您的位置:首页 > 其它

栈的应用之表达式求值(算符优先法)

2015-10-30 16:11 465 查看
为了简化问题,我们只考虑+、-、*、/四种运算,他们的优先级规则:

(1)先乘除,后加减

(2)从左算到右

(3)先括号内,再括号外



为了实现算符优先算法,需要两个工作栈,一个用来存放操作数(CZS),一个用来存放运算符(YSF)。

算法的基本思想:

(1)首先置操作数栈、运算符栈均为空,将‘#’压入运算符栈。

(2)依次读入表达式中的每个字符,如果是操作数则直接压入操作数栈(当然,操作数可能不是一位数,可以先用字符串保存每次读入的字符,再转为Int型,压入操作数栈)。如果是运算符,则需要与运算符栈顶元素比较。若运算符栈顶字符的优先级高于当前预算符,出现句柄,需要从操作数栈中弹出两个操作数,从运算符栈顶弹出一个运算符,进行运算后将结果压入操作数栈,注意,此时并没有读入下一个字符,还是用当前字符和栈顶字符比较;若运算符栈顶字符优先级小于当前字符,则直接将当前字符压入运算符栈,读入下一个字符;若运算符栈顶字符的优先级等于当前字符,如’(‘和’)’,则运算符栈弹出一个元素,读入下一个字符。

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

# define MAX 100

//运算符
typedef struct{
char data[MAX];
int top;
}Operator;

//操作数
typedef struct{
int data[MAX];
int top;
}Operand;

int operate(int a,char theta,int b);
void InitStack(Operator &s);
void InitStack(Operand &s);
int Push(Operator &s,char c);
int Push(Operand &s,int a);
int Pop(Operator &s);
int Pop(Operand &s);
char getTop(Operator &s);
int getTop(Operand &s);
char Precede(char a,char b);

int main()
{
Operator YSF;//运算符栈
Operand CZS;//操作数栈
char num[15];
InitStack(CZS);
InitStack(YSF);
Push(YSF,'#');
printf("-------四则运算(加减乘除),输入以#号结束--------\n");
char ch=getchar();
while(ch!='#'||getTop(YSF)!='#')
{
int i=0,a,b,flag=0;
char theta;
while(ch>='0'&&ch<='9')
{
flag=1;
num[i++]=ch;
ch=getchar();
}
if(flag)
{
num[i]='\0';
Push(CZS,atoi(num));
}
if(ch<'0'||ch>'9')
{
switch(Precede(getTop(YSF),ch))
{
case '>':
theta=getTop(YSF);
Pop(YSF);
b=getTop(CZS);
Pop(CZS);
a=getTop(CZS);
Pop(CZS);
Push(CZS,operate(a,theta,b));
break;
case '=':
Pop(YSF);
ch=getchar();
break;
case '<':
Push(YSF,ch);
ch=getchar();
break;
}
}
}
printf("%d\n",getTop(CZS));
return 0;
}

int operate(int a,char theta,int b)
{
if(theta=='+')
return a+b;
else if(theta=='-')
return a-b;
else if(theta=='*')
return a*b;
else if(theta=='/')
return a/b;
}

void InitStack(Operator &s)
{
memset(s.data,0,MAX*sizeof(char));
s.top=0;
}

void InitStack(Operand &s)
{
memset(s.data,0,MAX*sizeof(int));
s.top=0;
}

int Push(Operator &s,char c)
{
if(s.top>=MAX)
return 0;
else
{
s.data[s.top]=c;
s.top++;
return 1;
}
}

int Push(Operand &s,int a)
{
if(s.top>=MAX)
return 0;
else
{
s.data[s.top]=a;
s.top++;
return 1;
}
}

int Pop(Operator &s)
{
if(s.top==0)
return 0;
else
{
s.top--;
s.data[s.top]=0;
return 1;
}
}

int Pop(Operand &s)
{
if(s.top==0)
return 0;
else
{
s.top--;
s.data[s.top]=0;
return 1;
}
}

char getTop(Operator &s)
{
return s.data[s.top-1];
}

int getTop(Operand &s)
{
return s.data[s.top-1];
}

//比较两个运算符的优先级,a运算符在b左边
char Precede(char a,char b)
{
if(a=='+'||a=='-')
{
if(b=='+'||b=='-'||b==')'||b=='#')
return '>';
else
return '<';
}
else if(a=='*'||a=='/')
{
if(b=='(')
return '<';
else
return '>';
}
else if(a=='(')
{
if(b=='+'||b=='-'||b=='*'||b=='/'||b=='(')
return '<';
else if(b==')')
return '=';
else
{
printf("输入有误");
return 0;
}
}
else if(a==')')
{
if(b=='+'||b=='-'||b=='*'||b=='/'||b==')'||b=='#')
return '>';
else if(b=='(')
{
printf("输入有误");
return 0;
}
}
else if(a=='#')
{
if(b==')')
{
printf("输入有误");
return 0;
}
else if(b=='#')
return '=';
else
return '<';
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: