《《我想问的就是,为什么下面这个代码我运行时报错,但提交到OJ上就能过了.这是怎么回事?》》
题目如下,
利用栈编写表达式求值程序:输入含有“+”“-”“*”“/”四则运算的表达式,其中负数要用(0-整数)表示,并以“=”结束。(在这个程序中“#”也可以)。要求输出表达式的值。 测试样例格式说明: [键盘输入] 第一行:一个算数表达式 [正确输出] 第一行:算数表达式的值
测试样例: [第一组自测数据] [键盘输入] 3*(9-7)# [正确输出] 6
[第二组自测数据] [键盘输入] (0-12)*((5-3)*3)/(2+2)= [正确输出] -18
#include<stdio.h> #include<stdlib.h> #include<math.h> #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define ERROR 0 #define OK 1 struct SNum { int *base; int *top; int stacksize; };//数字栈 struct SChar { char *base; char *top; int stacksize; };//字符栈 int InitSNum(struct SNum &S) { //初始化数字栈 S.base = (int *)malloc(STACK_INIT_SIZE * sizeof(int)); if(!S.base) return 0; S.top = S.base; S.stacksize = STACK_INIT_SIZE; return OK; } int InitSChar(struct SChar &S)//初始化字符栈 { S.base = (char *)malloc(STACK_INIT_SIZE * sizeof(char)); if(!S.base) return 0; S.top = S.base; S.stacksize = STACK_INIT_SIZE; return OK; } int PushN(SNum &S,int e) //插入数字栈 { if(S.top-S.base>=S.stacksize) { S.base = (int *)realloc(S.base,(S.stacksize + STACKINCREMENT)*sizeof(int)); if(!S.base) return 0; S.top = S.base + S.stacksize; S.stacksize +=STACKINCREMENT; } *S.top++ = e; return OK; } int PushC(SChar &S,char e) //插入字符栈 { if(S.top-S.base>=S.stacksize) { S.base = (char *)realloc(S.base,(S.stacksize + STACKINCREMENT)*sizeof(char)); if(!S.base) return 0; S.top = S.base + S.stacksize; S.stacksize +=STACKINCREMENT; } *S.top++ = e; return OK; } int PopN(SNum &S,int &e) // 删除数字栈的栈顶元素,用e返回其值,并返回OK;否则返回ERROR { if(S.top == S.base) return ERROR; e = *--S.top; return OK; } int PopC(SChar &S,char &e) // 删除字符栈的栈顶元素,用e返回其值,并返回OK;否则返回ERROR { if(S.top == S.base) return ERROR; e = *--S.top; return OK; } int GetTopN(SNum S,int &e) // 若数字★★栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR { if(S.top == S.base) return ERROR; e = *(S.top-1); return OK; } int GetTopC(SChar S,char &e) // 若字符★★栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR { if(S.top == S.base) return ERROR; e = *(S.top-1); return OK; } int CheckChar(char c)//检查字符是什么 { if(c=='-'||c=='+'||c=='*'||c=='/')//加减乘除返回1 return OK; else if(c=='('||c==')')//括号返回2 return 2; else if(c=='#'||c=='=')//#和=返回3 return 3; else if(c>='0'&&c<='9')//数字,返回4 return 4; else return ERROR; } int TurnNum(char c,int &e) { //将字符转化为整型 switch(c) { case '0' : e=0; break; case '1' : e=1; break; case '2' : e=2; break; case '3' : e=3; break; case '4' : e=4; break; case '5' : e=5; break; case '6' : e=6; break; case '7' : e=7; break; case '8' : e=8; break; case '9' : e=9; break; default: return ERROR; } return OK; } void CleanArray(int n[10]) { //将数组全部置为-1 int i; // printf("\nThe Running Thing Is CleanArray\n");//测试语句★★★★★★★★★★ for(i=0;i<10;i++) { n[i]=-1; // printf("n[%d] is %d\n",i,n[i]);//测试语句★★★★★★★★★★ } } int Compute(struct SNum &A,struct SChar &B,int &x) { //计算 char k; int a,b; // printf("\nNow Run The Compute!!\n");//测试语句★★★★★★★★★★ if(!PopC(B,k)) return ERROR; if(!PopN(A,b)||!PopN(A,a)) return ERROR; // printf("\nWe read out the number %d and %d\n",b,a);//测试语句★★★★★★★★★★ // printf("\nAnd the char %c\n",k);//测试语句★★★★★★★★★★ //如果两个栈不能读出要用的所有数据,返回ERROR switch(k) { case '+' : x = a+b; break; case '-' : x = a-b; break; case '*' : x = a*b; break; case '/' : x = a/b; break; default : return ERROR;//如果不是运算符,返回ERROR } return OK; } char Precede(char a,char b)//比较运算符优先级 { if(a=='+'||a=='-') { if(b=='+'||b=='-'||b==')'||b=='#'||b=='=') return '>'; else return '<'; } else if(a=='*'||a=='/') { if(b=='(') return '<'; else return '>'; } else if(a=='(') { if(b==')') return '='; else if(b=='#'||b=='=') return ERROR; else return '<'; } else if(a==')') { if(b!='(') return '>'; } else { if(b=='#'||b=='=') return '$'; else if(b!=')') return '<'; } } int main() { char c,v; int a[10],i,e=0,x,m; struct SNum N; struct SChar C; InitSNum(N); InitSChar(C); PushC(C,'#'); c=getchar(); GetTopC(C,v); CleanArray(a); while(c!='#'&&c!='='||v!='#') { i=0; e=0; // GetTopC(C,v);//测试语句★★★★★★★★★★ // printf("Before The ELSE We Get The Top Of CharStack %c\n",v);//测试语句★★★★★★★★★★ if(4==CheckChar(c)) { while(4==CheckChar(c))//假如字符代表的是数字,就转换 { TurnNum(c,a[i]); // printf("第一种转换数字后%d\n",a[i]);//测试语句★★★★★★★★★★ m=i; // printf("这时m = %d\n",m);//测试语句★★★★★★★★★★ i++; scanf("%c",&c); } if(!CheckChar(c)) return 0;//假如输入字符有错,退出 for(i=0;a[i]!=-1;i++)//将分散的数字转换成原本的有几位的数字 { e+=a[i]*pow(10,m); // printf("Now a[i] is a[%d] %d\n",i,a[i]);//测试语句★★★★★★★★★★ // printf(" 第二种转换后数字是 %d\n",e);//测试语句★★★★★★★★★★ m--; } if(i!=0)//数字入栈 { PushN(N,e); // GetTopN(N,e);//测试语句★★★★★★★★★★ // printf("数字入栈后%d\n",e);//测试语句★★★★★★★★★★ e=0; CleanArray(a); } if(i!=0) i=0; if(c=='(') { PushC(C,c); c=getchar(); }//是左括号就入栈 }//不是运算符就入栈 else { // printf("Now we enter the ELSE!!\n");//测试语句★★★★★★★★★★ GetTopC(C,v); // printf("We Get The Top Of CharStack %c\n",v);//测试语句★★★★★★★★★★ // printf("now the c is %c\n",c);//测试语句★★★★★★★★★★ switch(Precede(v,c)) { case '<' : // printf("Now we enter the '<' of ELSE!!\n");//测试语句★★★★★★★★★★ PushC(C,c); c=getchar(); break; case '=' : // printf("Now we enter the '=' of ELSE!!\n");//测试语句★★★★★★★★★★ PopC(C,v); c=getchar(); break; case '>' : // printf("Now we enter the '>' of ELSE!!\n");//测试语句★★★★★★★★★★ Compute(N,C,e); PushN(N,e); // printf("Place 2 : Pushed int is %d\n",e);//测试语句★★★★★★★★★★ break; case '$' : // printf("Now we enter the '$' of ELSE!!\n");//测试语句★★★★★★★★★★ GetTopN(N,e); if(!Compute(N,C,x)) { PushN(N,e); // printf("Place 3 : Pushed int is %d\n",e);//测试语句★★★★★★★★★★ } else { PushN(N,x); // printf("Place 4 : Pushed int is %d\n",e);//测试语句★★★★★★★★★★ } break; } } } GetTopN(N,e); printf("%d\n",e); }