用两种方式实现表达式自动计算
}
/*定义函数,用于计算两个数的加减乘除*/ double re(double a,double b,char op) { }
void main() {
char c;
char inorder[100]; char postorder[100]; int inpos,postpos; int i;
double od_a,od_b,result; char *p=NULL;
/*用于后缀表达式计算*/ /*字符转换为double时的指针*/
/*中缀表达式*/ /*后缀表达式*/ /*表达式被扫描的位置*/
switch(op) { }
case '+':return a+b;
break;
/*返回a和b的差*/ /*返回a和b的积*/ /*返回a和b的商*/
/*如果b=0,返回0,计算会出错,但程序不会强行终止*/ /*返回a取余b的值*/ /*否则返回0*/
break; break;
else return a/b;
case '-':return a-b; case '*':return a*b;
/*返回a和b的和*/
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;
/*如果是/、*或%,返回3*/ /*否则返回0*/ /*如果是+或-,返回0*/ /*#为op栈初始时的栈底元素*/ /*如果是#或),返回0*/ /*如果是(,返回1*/
case '/':if(b==0.0)return 0;
break; break;
case '%':return (int)a%(int)b; default:return 0;break;
- 6 -
用两种方式实现表达式自动计算
op->str[0]='#'; */
op->top_op=0; od->top_od=-1;
/*完成中缀变后缀,仍然用字符表示数字,存储在字符数组postorder[100]中*/ inpos=0,postpos=0; {
c=inorder[inpos]; if(c>='0'&&c<='9') {
i=inpos; { }
postorder[postpos++]=inorder[i]; i++;
postorder[postpos++]=' '; inpos=i;
/*如果是操作符*/
/*空格作为分隔符,防止两个数字重叠*/
/*将数字整个字符复制到postorder[100]中*/
while(inorder[i]>='0'&&inorder[i]<='9'||inorder[i]=='.')
/*如果是数字*/
/*初始化扫描位置*/
while(inorder[inpos]!='\\0')/**/
printf(\输入一个中缀表达式(先算后缀表达式,再计算):\\n\gets(inorder);
/*获取一个中缀表达式*/
/*op栈栈顶指针为0*/ /*od栈栈顶指针为-1*/
/*作为栈低,当进行op栈的入栈操作时,不用再判断栈空
struct opnode oplist; struct opnode *op; struct odnode *od; op=&oplist; od=&odlist;
struct odnode odlist;
/*定义op栈oplist*/ /*定义op栈的指针*/ /*定义od栈odlist*/ /*定义od栈的指针*/ /*通过op指针访问oplist栈*/ /*通过od指针访问odlist栈*/
}
if(is_op(c)) {
if(level(c)>level(top_op(op))||c=='(') /*操作符优先级高或者是'(',将操作符压栈*/ {
while(top_op(op)!='(') { }
/*从op栈中取出的操作符,除'('*/ /*外,依次放入postorder[100]中*/
{ }
/*操作符是')',出栈到有'('为止*/
push_op(op,c);
else if(c==')')
postorder[postpos++]=top_op(op); pop_op(op);
- 7 -
用两种方式实现表达式自动计算
} }
while(op->top_op>0) {
/*如果栈此时不为空,一直出栈直到栈空*/ /*op栈栈底为'#',不是操作符,不用取出*/
}
else if(level(c)<=level(top_op(op))) { } inpos++;
while(level(c)<=level(top_op(op))) /*执行循环操作,直到此操作符能入栈为止*/ { }
/*将此操作符压栈*/
/*取出op栈顶元素放入postorder[100]中*/
postorder[postpos++]=top_op(op); pop_op(op);
/*如果此操作符优先级低于栈顶元素*/
pop_op(op);
/*将'('从op栈中去掉*/
push_op(op,c);
postorder[postpos++]=top_op(op); pop_op(op); }
postorder[postpos]='\\0';
/*计算后缀表达式,取出字符时再转换为double类型*/ op->str[0]='#'; op->top_op=0; i=0; {
c=postorder[i]; if(c>='0'&&c<='9') { }
if(is_op(c)) {
od_b=top_od(od); pop_od(od);
/*从栈中取出两个数字*/ /*分别赋值给od_b和od_a*/
/*如果是操作符*/
p=&postorder[i]; od_a=atof(p);
push_od(od,od_a); { } i--;
/*将i置为此数字字符的最后一个位置*/
i++;
/*将指针*p指向此数字字符所在的位置*/ /*用函数atof()将字符转换为double类型*/ /*将此数压入od栈*/
/*如果是0-9的字符*/
/*postorder[100]的扫描位置索引,赋值为0*/ /*strlen()返回值为无符号的整形,强制转换为整形*/
while(i<(int)strlen(postorder))
/*再次重置栈,栈底放入'#',栈顶指针为0*/
/*postorder[100]最后用'\\0'作为结束标志*/
while(postorder[i]>='0'&&postorder[i]<='9'||postorder[i]=='.')
- 8 -
用两种方式实现表达式自动计算
} i++; }
/*扫描索引位置加1,开始下一次扫描*/ /*while循环结束后,结果位于od栈的栈顶*/ /*将结果取出,赋值给result*/ /*提示信息*/ /*输出中缀表达式*/ /*提示信息*/ /*输出后缀表达式*/ /*输出结果*/ /*提示信息*/ /*实现按任意键退出*/
od_a=top_od(od); pop_od(od);
result=re(od_a,od_b,c); push_od(od,result);
/*计算两个数的运算结果*/ /*将结果压入od栈中*/
result=top_od(od); puts(inorder);
printf(\中缀表达式:\ printf(\后缀表达式:\ puts(postorder); printf(\结果=%f\ getch(); }
printf(\按任意键退出!\
下面给出的是直接计算的程序的源代码:
/******************************/ /* 程序名称:stack_2.c */ /* 计算多项式,进栈时直接计算*/ /*****************************/ #include \#include \#include \
#define MAX 100
struct opnode { };
struct odnode { };
void push_op(struct opnode *op,char c) /*定义op栈的进栈函数*/ {
if(op->top_op>=MAX-1) { }
/*如果栈满,不进行操作*/
double num[MAX]; int top_od;
/*声明od栈*/
char str[MAX]; int top_op;
/*声明op栈*/
/*定义栈的最大长度*/
/*包含库函数*/
- 9 -
用两种方式实现表达式自动计算
}
void pop_op(struct opnode *op) /*定义op栈的出栈函数*/
else { }
op->top_op++; op->str[op->top_op]=c;
/*否则,进行进栈操作*/
{ if(op->top_op<=-1)
{ }
else
{ op->top_op--;
}
}
char top_op(struct opnode *op)
{ return(op->str[op->top_op]);
}
/***************/
void push_od(struct odnode *od,double d) { if(od->top_od>=MAX-1)
{ } else
{ od->top_od++;
od->num[od->top_od]=d; }
}
void pop_od(struct odnode *od)
{ if(od->top_od<=-1)
{ }
else
{ od->top_od--;
}
/*如果栈为空,不进行操作*/ /*否则,进行出栈操作*/
/*定义op栈的看栈顶的函数*/
/*定义od栈的进栈函数*/
/*如果栈为满,不进行操作*/ /*否则,进行进栈操作*/
/*定义od栈的出栈函数*/
/*如果栈为空,不进行操作*/ /*否则,进行出栈操作*/
- 10 -