| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 889 人关注过本帖
标题:请同时具有耐心和热心的版主进来看一下!!!
只看楼主 加入收藏
dimyself
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2004-10-18
收藏
 问题点数:0 回复次数:5 
请同时具有耐心和热心的版主进来看一下!!!

我写了个计算器的程序(还未完善所有功能!),遇到点问题,主要是计算结果(有时对有时错)

我查了很久,也未果!故请版主们来看一下,谢啦!

程序如下:

#define MAX 100 #include<stdio.h> #include<stdlib.h> #include<math.h> typedef struct { float value;//数值 char charc[5];//运算符 }link;//结构体用于存放处理后的表达式(即是数值与运算符的集合) float operS(float c)//求一个数的开方 { float temp; temp=sqrt(c); return(temp); }

int operA(int a,int b)//求排列 { int i,sn; sn=1; for(i=a;i>=a-b+1;i--) sn=sn*i; return(sn); }

int operC(int a,int b)//求组合 { int temp,i,sn,tn; sn=1; for(i=a;i>=a-b+1;i--) sn=sn*i; tn=1; for(i=b;i>0;i--) tn=tn*i; temp=sn/tn; return(temp); }

int operX(int a,int b)//求a的b次方 { int i,sn=1; for(i=1;i<=b;i++) sn=sn*a; return(sn); }

int operN(int a)//求阶乘 { int i,sn; sn=1; for(i=a;i>0;i--) sn=sn*i; return(sn); }

calculation(link exp[],int k)//计算求值 { int i,j,t; for(i=1;i<=k;i++) for(j=1;exp[i].charc[j]!='#';j++)//即是后缀表达式中数值后面跟有运算符的就求值 switch(exp[i].charc[j]) { case'+':for(t=i-1;exp[t].value!=0&&t>0;t--)//向前看第一个exp[t].value不为0的值 { exp[i].value=exp[t].value+exp[i].value; exp[t].value=0;//计算之后便把它置0,新值保留在exp[i].value中 break; } case'-':for(t=i-1;exp[t].value!=0&&t>0;t--)//四则计算 { exp[i].value=exp[t].value-exp[i].value; exp[t].value=0; break; } case'*':for(t=i-1;exp[t].value!=0&&t>0;t--) { exp[i].value=exp[t].value*exp[i].value; exp[t].value=0; break; } case'/':for(t=i-1;exp[t].value!=0&&t>0;t--) { exp[i].value=exp[t].value/exp[i].value; exp[t].value=0; break; } } printf("表达式的值为:\n"); printf("%f",exp[k].value); }

void turn()//将表达式转换成后缀表达式,在这一过程中还求出了S(),A(),C()等的值 { int i,j,k,t,top,num,temp,sum1,sum2; float sum,su,tem; char expr[MAX],stack[MAX];//expr[]内放初始表达式,stack[]用作符号栈 link exp[MAX]; i=0;k=0;t=0;top=1;//k为表达式所含数值个数 printf("请输入要求值的表达式:\n"); do { i++; scanf("%c",&expr[i]); }while(expr[i]!='#'&&i<=MAX);//输入表达式 num=i; printf("原表达式为:\n"); for(i=1;i<=num;i++) printf("%c",expr[i]); printf("\n"); i=1; while(expr[i]!='#') { switch(expr[i]) { case'S':sum=0.0;su=0.0;tem=0.1;//是求S()的 i=i+2; while(expr[i]>='0'&&expr[i]<='9')//可能是小数 { sum=sum*10+expr[i]-48; i++; } if(expr[i]=='.') { i++; while(expr[i]>='0'&&expr[i]<='9') { su=su+(expr[i]-48)*tem; tem=tem*(0.1); i++; } } i++; sum=sum+su; exp[++k].value =operS(sum);//放入exp[]中 sum=0.0;su=0.0;//重新置0 break; case'A':sum1=0;sum2=0;t1=0;t2=0;//是求排列的 for(i=i+2;expr[i]!=',';i++)//前一个数 { t1++; sum1=sum1*10+expr[i]-48;; } for(i=i+1;expr[i]!=')';i++)//后一个数 { t2++; sum2=sum2*10+expr[i]-48; } i++; exp[++k].value=operA(sum1,sum2);//求值并保存 break; case'C':sum1=0;sum2=0;t1=0;t2=0;//求组合 for(i=i+2;expr[i]!=',';i++)//前一个数 { t1++; sum1=sum1*10+expr[i]-48; } for(i=i+1;expr[i]!=')';i++)//后一个数 { t2++; sum2=sum2*10+expr[i]-48; } i++; exp[++k].value=operC(sum1,sum2); break; case'^':sum1=0;sum2=0;t1=0;t2=0;temp=1;//求次方 for(j=i-1;expr[j]>='0'&&expr[j]<='9';j--)//基数 { t1++; sum1=sum1+(expr[j]-48)*temp; temp=temp*10; } for(i=i+1;expr[i]>='0'&&expr[i]<='9';i++)//幂 { t2++; sum2=sum2*10+expr[i]-48; } k--; exp[++k].value=operX(sum1,sum2); break; case'!':sum1=0;t1=0;temp=1;//阶乘 for(j=i-1;expr[j]>'0'&&expr[j]<'9';j--) { t1++; sum1=sum1+(expr[j]-48)*temp; temp=temp*10; } i++; k--; exp[++k].value=operN(sum1); break; case'(':stack[++top]=expr[i++];//当前是左括号便进栈 break; case')':while(stack[top]!='('&&top!=1)//当前是右括号则把栈内所有运算符出栈 exp[k].charc[++t]=stack[top--]; top--;//左括号也出栈 i++; break; case'*': case'/':while(stack[top]=='*'||stack[top]=='/')//当前是*或/,如果栈顶是*或/则把栈顶出栈 exp[k].charc[++t]=stack[top--]; stack[++top]=expr[i++]; break; case'+': case'-':while(stack[top]!='('&&top!=1)//当前是+或-则把比它优先级高的运算符(既*或/)出栈 exp[k].charc[++t]=stack[top--]; stack[++top]=expr[i++]; break; default:sum=0.0;su=0.0;tem=0.1;//当前是数字则直接进栈 while(expr[i]>='0'&&expr[i]<='9') { sum=sum*10+expr[i]-48;//整数部分 i++; } if(expr[i]=='.')//小数部分 { i++; while(expr[i]>='0'&&expr[i]<='9') { su=su+(expr[i]-48)*tem; tem=tem*(0.1); i++; } } exp[++k].value=sum; exp[k].charc[++t]='#';//后缀表达式中数字后面没有运算符的话便把#放到exp[].charc[1]中 t=0; break; } } while(top!=1)//把栈内剩下的运算符出栈 exp[k].charc[++t]=stack[top--]; exp[k].charc[++t]='#'; printf("转换成后缀表达式并放入表后的分布:\n"); for(i=1;i<=k;i++) printf("%10f",exp[i].value); printf("\n"); for(i=1;i<=k;i++) for(j=1;exp[i].charc[j]!='#'&&j<5;j++) if(exp[i].charc[j]=='+'||exp[i].charc[j]=='-'||exp[i].charc[j]=='*'||exp[i].charc[j]=='/') printf("%3c",exp[i].charc[j]); printf("%c%c",exp[1].charc[1],exp[2].charc[1]);//输出后缀表达式中数值和运算符 printf("\n"); calculation(exp,k);//调用子函数进行计算求值 }

务必请哪为好心的版主花点时间看一下,给我指出错误在哪???(程序可运行,主函数很简单,就是调用子函数turn())

衷心感谢!!!

搜索更多相关主题的帖子: 版主 热心 耐心 
2004-11-04 20:57
天使预备役
Rank: 2
等 级:论坛游民
威 望:3
帖 子:670
专家分:10
注 册:2004-4-6
收藏
得分:0 

如果是结果不对,就应该是你算法的问题了,仔细看看!!!


差点把你忘了...
2004-11-05 09:41
dimyself
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2004-10-18
收藏
得分:0 

若是算法问题,那就只可能出现在计算求值函数calculation里,因为前面的中缀表达式转换成后缀表达式的结果总是正确的,

但我都看了几次了,还是没发现哪出了问题!

版主啊,你若是有空的话,就帮我看一下喽!

2004-11-05 10:10
Knocker
Rank: 8Rank: 8
等 级:贵宾
威 望:47
帖 子:10454
专家分:603
注 册:2004-6-1
收藏
得分:0 
简化你的程式,只把主函数与错误的部分贴上来,运行正确的部分删去,再一个,子函数从简,要让人一眼就能看明白。不然,谁有那么多精力来查看你那上百行的程式?

九洲方除百尺冰,映秀又遭蛮牛耕。汽笛嘶鸣国旗半,哀伤尽处是重生。     -老K
治国就是治吏。礼义廉耻,国之四维。四维不张,国之不国。   -毛泽东
2004-11-05 11:55
一点过去
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2004-11-5
收藏
得分:0 
晕晕的……
2004-11-05 15:34
dimyself
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2004-10-18
收藏
得分:0 

我重新看了一遍,在calculation函数里面出了点问题,但也只是解决了一部分!

calculation函数如下:

calculation(link exp[],int k) { int i,j,t=0; i=1; while(i<=k) { if(exp[i].charc[1]!='#') { for(j=1;exp[i].charc[j]!='#';j++) switch(exp[i].charc[j]) { case'+':t=i-1; while(t>0) { if(exp[t].value==0) t--; else { exp[i].value=exp[t].value+exp[i].value; exp[t].value=0; break; } }//while end case'-':t=i-1; while(t>0) { if(exp[t].value==0) t--; else { exp[i].value=exp[t].value-exp[i].value; exp[t].value=0; break; } }//while end case'*':t=i-1; while(t>0) { if(exp[t].value==0) t--; else { exp[i].value=exp[t].value*exp[i].value; exp[t].value=0; break; } }//while end case'/':t=i-1; while(t>0) { if(exp[t].value==0) t--; else { exp[i].value=exp[t].value/exp[i].value; exp[t].value=0; break; } }//while end }//switch end i++; }//if end else i++; }//while end printf("表达式的值为:\n"); printf("%f",exp[k].value); }

虽然turn函数总是能得到正确的结果,但我总觉得它有问题!

它里面的变量k的值一直在变化,每执行一条语句就加1,但最后却又是正确的个数!我跟踪了几遍都没弄明白

turn函数已经在上面有了,我就不贴了,免得...

总之谢谢以上几位,因为总还有人看了偶的!谢啦!

如果下一贴有谁能跟我指出哪里错了...那就太....好了!

合乎!

2004-11-05 17:37
快速回复:请同时具有耐心和热心的版主进来看一下!!!
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030053 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved