用两种方式实现表达式自动计算
}
double top_od(struct odnode *od)
{ return(od->num[od->top_od]);
}
/*判断是否为运算符*/ int is_op(char op)
{ switch(op)
{ case '(':return 1;break; case ')':return 1;break; case '+':return 1;break; case '-':return 1;break; case '*':return 1;break; case '/':return 1;break; case '%':return 1;break; default:return 0;break;
}
}
/*判断运算符优先级*/ int level(char op)
{ switch(op)
{ case '#':return 0;break; case ')':return 0;break; case '(':return 1;break;
case '+':return 2;break; case '-':return 2;break;
case '*':return 3;break; case '/':return 3;break; case '%':return 3;break;
default:return 0;break; }
} /*计算*/
double re(double a,double b,char op)
{
switch(op)
/*定义od栈看栈顶的函数*/
/*op为运算符*/
/*用switch语句判断*/
/*如果是运算符,返回1*/ /*否则,返回0*/
/*op为运算符*/
/*用switch语句判断,返回值为运算符的栈内优先级*/
/*'#'作为栈底元素*/ /*如果是'#'或')',返回0*/ /*如果是'(',返回0*/
/*如果是'+'或'-',返回2*/ /*如果是'*','/'或'%',返回3*/ /*计算两个浮点数的运算结果*/
/*用switch语句判断,op为运算符*/ - 11 -
用两种方式实现表达式自动计算
/*主函数*/ void main() {
int i,inpos;
/*inpos是inorder[100]的扫描索引*/ /*用于存储表达式*/ /*atof()函数所用的指针*/
char inorder[MAX]; char c,*p=NULL; double a,b,result; char temp_op;
struct opnode oplist; struct odnode odlist; struct opnode *op; struct odnode *od; op=&oplist; od=&odlist; od->top_od=-1; op->top_op=-1; c='#';
push_op(op,c);
printf(\输入一个中缀表达式(直接计算):\\n\提示信息*/ gets(inorder);
/*扫描表达式*/ i=0;
/*i作为扫描inorder[100]的辅助索引*/ /*初始化扫描索引*/
inpos=0;
/*接收表达式*/
/*向op栈栈底放入'#',用于进栈时判断优先级*/
/*初始化od栈*/ /*初始化op栈*/
/*定义op栈*/ /*定义od栈*/ /*定义op栈的指针*/ /*定义od栈的指针*/
{ }
case '+':return a+b;
break;
/*返回a和b的差*/ /*返回a和b的积*/ /*返回a和b的商*/
break; break;
else return a/b; break;
/*返回a取余b的结果*/ /*否则,返回0*/
break;
/*如果b=0,返回0,计算结果出错,但程序不会强行终止*/
case '-':return a-b; case '*':return a*b;
/*返回a和b的和*/
case '/':if(b==0.0)return 0;
case '%':return (int)a%(int)b; default:return 0;break;
}
c=inorder[inpos];
- 12 -
用两种方式实现表达式自动计算
while(c!='\\0')
/*用while循环扫描数组inorder[100]*/
{ 一个位置*/
c=inorder[inpos]; i=inpos;
if(c>='0'&&c<='9')
/*如果是数字字符*/
{ p=&inorder[i]; /*p指针指向此数字字符在数组中的位置*/ a=atof(p);
/*用atof()函数将数字字符转换为浮点型*/ push_od(od,a);
/*将数字压入od栈中*/
while(inorder[i]>='0'&&inorder[i]<='9'||inorder[i]=='.')
{ i++;
} i--; inpos=i;
/*将主索引和辅助索引置为此数字字符的最后
}
else if(is_op(c))
/*如果是操作符*/
{ if(level(c)>level(top_op(op))||c=='(') {
/*如果操作符优先级大,压入op栈中*/
push_op(op,c);
}
else if(c==')')
/*如果操作符是')'*/
{ temp_op=top_op(op); while(temp_op!='(')
/*从op栈中出栈,直到栈顶为'('*/
{ temp_op=top_op(op); pop_op(op);
/*从op栈中取出一个操作符*/
b=top_od(od); pop_od(od);
a=top_od(od); pop_od(od);
/*从od栈中依次取出两个数字*/
result=re(a,b,temp_op); /*计算两个数字的运算结果*/
push_od(od,result);
/*将结果压入od栈中*/
temp_op=top_op(op);
}
pop_op(op);
/*将'('出栈*/
- 13 -
用两种方式实现表达式自动计算
} {
result=top_od(od);
puts(inorder);
/*输出中缀表达式*/
/*从od栈中取出计算结果*/ /*提示信息*/
printf(\中缀表达式:\
temp_op=top_op(op); pop_op(op);
b=top_od(od); pop_od(od); a=top_od(od); pop_od(od);
result=re(a,b,temp_op);
push_od(od,result);
/*将结果压入od栈中*/
/*计算两个数字的运算结果*/
/*从od栈中依次取出两个数字*/
/*从op栈中取出一个操作符*/
}
inpos++;
/*主索引自加1,开始下一次扫描*/
c=inorder[inpos];
/* while循环结束后,表达式已扫描完毕*/
/*如果op栈中还有操作符*/
}
else if(level(c)<=level(top_op(op))) { }
do { }
while(level(c)<=level(top_op(op))); /*此while循环结束后,操作符可以入栈*/ push_op(op,c);
/*操作符压入op栈*/
temp_op=top_op(op); pop_op(op);
b=top_od(od); pop_od(od);
a=top_od(od); pop_od(od);
result=re(a,b,temp_op);
push_od(od,result);
/*将结果压入od栈中*/
/*计算两个数字的运算结果*/
/*从od栈中依次取出两个数字*/
/*从op栈中取出一个操作符*/
/*如果操作符优先级低*/
while(op->top_op>0)
}/*此while循环结束后,计算表达式结束,结果存放在od栈的栈顶*/
- 14 -
用两种方式实现表达式自动计算
}
printf(\结果=%f\getch();
/*输出结果*/ /*提示信息*/
/*实现程序按任意键退出*/
printf(\按任意键退出!\
四、运行结果
下面是两个程序的运行结果截图,第一个是先计算后缀表达式,再计算结果的程序截图,第二个是直接计算中缀表达式的程序截图。
图3 先算后缀,再算结果的运行结果图
图4 直接计算的运行结果图
- 15 -