中缀表达式求值

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、设计思想
用堆栈中缀法实现表达式自动计算的基本思路是:定义两个栈,一个为操作符栈,用来存放操作符的;另一个为操作数栈,用来存放操作数。

还有一个字符型数组,用来存放输入的表达式。

从数组中开始扫描第一个字符w,每扫描一个字符后,根据w的不同情况分别做以下处理:
如果是操作符,那么判断w与操作符的栈顶的优先级。

如果大于,直接将w压入操作符栈。

如果小于,则将操作符的栈顶弹栈,再将操作数栈的栈顶和次栈顶弹栈,并和操作符的栈顶进行计算,结果直接进入操作数栈。

如果w不是操作符,判断它是整数还是小数,是一位的还是多位的。

如果操作符的栈顶元素是#,并且从表达式数组中扫描进来的也是#,运算结束,操作数的栈顶元素就是计算结果。

二、算法流程图
中缀表达式求值算法流程图简单说明:
将输入的字符表达式存到数组中,对数组中的元素进行遍历,当读入第一个字符时先判断它是不是操作数然后判断它是不是多位浮点型小数。

如果是操作符,就判断它的优先级和操作符栈栈顶的优先级,谁的优先级比较高,如果是栈顶的优先级大于输入的字符,那么将栈顶的元素a出栈,再从操作数栈弹出栈顶和次栈顶,并进行次栈顶和栈顶关于a的运算,结果送回到操作数栈,然后扫描下一个字符。

如果它是操作数,那么要判断它是一位数还是多位数,是小数还是整数,如果是小数或者是多位的,那么执行多位数处理程序。

三、源代码
下面给出的是用中缀表达式求值算法实现的程序的源代码:#define N 50
#include<ctype.h>
#include<string.h>
#include<stdio.h>
#include<math.h>
typedef struct
{
int top;
double array[N];
}NumStack;//操作数栈类型
typedef struct
{
int top;
char array[N];
}OpStack;//操作符栈类型
int Cint(char mychar)
{
return (mychar-48);
}//字符转换成数字
void PushNum(NumStack *numstack,double num)
{
numstack->top++;
numstack->array[numstack->top-1]=num;
}//操作数进栈
void PopNum(NumStack *numstack,double*num)
{
*num=numstack->array[numstack->top-1];
numstack->top--;
}//操作数出栈
void PushOp(OpStack *opstack,char op)
{
opstack->top++;
opstack->array[opstack->top-1]=op;
}//操作符进栈
void PopOp(OpStack *opstack,char*op)
{
*op=opstack->array[opstack->top-1];
opstack->top--;
}//操作符出栈
double Calc(double a,double b,char c)
{
double result;
switch(c)
{
case'+':result=a+b;break;
case'-':result=a-b;break;
case'*':result=a*b;break;
case'/':result=a/b;break;
}
return result;
}//计算两个操作数按c进行运算
char Priority(char y,char x)
{
char priority='<';
switch(x)
{
case'+':
case'-':if(y=='('|| y=='#')priority='>';break;
case'*':
case'/':if(y=='('|| y=='#'|| y=='+'|| y=='-')priority='>';break;
case'(':priority='>';break;
case')':if(y=='(')priority='=';break;
case'#':if(y=='#')priority='=';break;
default:priority='E';
}
return priority;
}//比较两个操作符的优先级
void Process(NumStack *numstack,OpStack *opstack,char x)
{
double a,b;char c;
static double tempnum=0.00000000;static int len=10;static int
dot=0,flags=0;
if(isdigit(x) || x=='.'){
if(x=='.')dot=1;
else
{
if(dot==0)
tempnum=tempnum*10+Cint(x);//整数部分两位以上的数
else
{
tempnum=tempnum+(double)Cint(x)/len;//小数部分两位以上的数
len*=10;
}
}
}
else
{
if(flags==0 &&
x!='('){PushNum(numstack,tempnum);tempnum=0.00000000;len=10;dot=0;} switch(Priority(opstack->array[opstack->top-1],x))
{
case'>':PushOp(opstack,x);flags=0;break;
case'<':
PopOp(opstack,&c);
PopNum(numstack,&b);
PopNum(numstack,&a);
PushNum(numstack,Calc(a,b,c));flags=1;
Process(numstack,opstack,x);break;
case'=':PopOp(opstack,&c);flags=1;break;
default:printf("Wrong Express!");exit(0);
}
}
}
main()
{
NumStack numstack;OpStack opstack;//定义栈
char s[N];int i=0;
numstack.top=0;opstack.top=0;//初始化栈
PushOp(&opstack,'#');//操作符栈底为#
printf("\nEnter your expression and end it with #:");scanf("%s",s); for(i=0;i<strlen(s);i++)
Process(&numstack,&opstack,s[i]);
printf("The result is %f",numstack.array[numstack.top-1]);
}。

相关文档
最新文档