求实现直接输入表达式回车的计算器算法。。!谢谢!
我想做一个计算器程序,直接输入比如 1+2然后回车出结果。
可是我怎么设计都设计不出来算法。。我只能做出来 比如输入1回车 输入+回车 输入2回车 然后出结果。。
求高手解答。。
新手刚刚学习。谢谢了!
我的代码如下。。
第一部分是我做出来的
第二部分代码是我按照我想的做的 我使用数组来进行输入 可是 1 + 2 这三个分别是数字和字符 我定义数字数组 和字符数组都不能包括。。
我一开始定义的 实数数组 想用gets()来接受输入 然后将第二个值在转化为字符,可是我忘了用gets()1和2都变成字符了。。。
百思不得其解啊。。
求方法!
代码如下。。
[code=C/C++][/code]
#include<stdio.h>
int main()
{
float x,y;
char z,a;
A:printf("请输入第一个数值并按回车结束!\n");
scanf("%f",&x);
fflush(stdin);
printf("请输入运算符并按回车结束!\n");
scanf("%c",&z);
fflush(stdin);
printf("请输入第二个数值并按回车结束!\n");
scanf("%f",&y);
fflush(stdin);
if(z=='+')
printf("\n程序运行结果为\n%g+%g=%g",x,y,x+y);
if(z=='-')
printf("\n程序运行结果为\n%g+%g=%g",x,y,x-y);
if(z=='*')
printf("\n程序运行结果为\n%g*%g=%g",x,y,x*y);
if(z=='/')
printf("\n程序运行结果为\n%g/%g=%g",x,y,x/y);//晕,忘了实数不能对实数求余,怪不得一直弹错误!
printf("\n此程序曹宇制作,请购买正版,谢谢支持!\n\n如果要继续计算请输入y并按回车!\n如想退出请输入任意字符并按两次回车关闭程序!\n");
scanf("%c",&a);
if(a=='y')
goto A;
else goto B;
B:printf("\n此程序曹宇制作,请购买正版,谢谢支持!\n");
getchar();
getchar();
return 0;
}
/* 这些为我想的那种输入方法的代码,可是没有办法实现。。。
#include<stdio.h>
int main()
{
int i;
char a,char_b; //我想写成直接输入入1+2然后回车就出结果的,但是这个表达式两个定义是实型一个是字符
double s[10]; //我定义入左边的实型数组那么怎么弄都不能输入表达式回车 必须如 输入1回车 输入+回车 输入2回车
A:printf("请输入你的计算表达式,并按回车结束!\n");//如果我用gets()或者用循环使用getchar()是可以直接直接输入不回车
for(i=0;i<9;i++) //但是这样我的计算数据 1 2 就变成字符了 计算就是49+50了
{
s[i]=getchar(); //这里正确的应该是scanf("%f",&s[i]);可是这样弄,就必须输入一个按一次回车。就算一次输入多个变量也要设置分隔符,头疼啊!
if(s[i]=='\n') //如果用scanf("%f",&s[i]);那么这一句if语句可以不要了,循环次数改成3次就能退出循环了。。
goto L;
}
L:char_b=s[1]; //这个语句是我一开始的错误想法没想到输入的数值也会变成数组(就是我输入1+2变成了49+50)的时候想的将这个
printf("aaa%c\n",f); //s[1]转换成字符,可是我并没有想到这是多余的 并且计算的数值都变成字符了。。。
if (char_b=='+')
printf("%g+%g=%g\n",s[0],s[2],s[0]+s[2]);
if (char_b=='-')
printf("%g-%g=%g\n",s[0],s[2],s[0]-s[2]); //求大神指教方法啊 如何完成如直接输入1+2按回车就能计算的代码。。谢谢了!
if (char_b=='*')
printf("%g*%g=%g\n",s[0],s[2],s[0]*s[2]);
if (char_b=='/')
printf("%g/%g=%g\n",s[0],s[2],s[0]/s[2]);
fflush(stdin);
printf("你还想不想继续计算,继续计算请输入y并按回车结束,否则输入n按回车结束或者按红叉!\n");
scanf("%c",&a);
fflush(stdin);
if (a=='y')
goto A;
else goto B;
B:return 0;
}
*/
[解决办法]
这种算式计算是需要用到特定的算法,建议楼主学习一下 栈的用法,栈是解决这类问题的关键。
[解决办法]
你是四则运算吗?看数据结构中 后缀表达式等相关信息,
若仅是两个数的 +、-、*、/ 计算,则会简单许多。
double d1,d2,d3;
char c;
scanf(" %lf %c %lf", &d1, &c, &d2);
if(c=='+')d3=d1+d2;
。。。
[解决办法]
呵呵,如果想编一个简单的计算器,你可以尝试一下开关语句:下面是我的程序,你可以参考:
#include<stdio.h>
void main()
{float x,y;
char op;
printf("enterX,opretion&y:");
scanf("%f%c%f",&x,&op,&y);
switch(op)
{case'+':
printf("%.2f%c%.2f=%.2f\n",x,op,y,x+y);
{case'-':
printf("%.2f%c%.2f=%.2f\n",x,op,y,x-y);
{case'*':
printf("%.2f%c%.2f=%.2f\n",x,op,y,x*y);
case'/':
if(y==0.0)printf("error\n");
else
printf("%.2f%c%.2f=%.2f\n",x,op,y,x/y);
}}
这个要比你的方法要好!也简单,更符合你的要求啦。
[解决办法]
要界面吗,一个edit空间外加字符串解析,很简单的 ……
[解决办法]
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<ctype.h>#define MAXSIZE 50#define IS_OPND(ch) (((ch)=='+')||((ch)=='-')||((ch)=='/')||((ch)=='*'))struct char_stack{ char ch_arr[MAXSIZE]; int top;};struct int_stack{ int int_arr[MAXSIZE]; int top;};static int tag;int calval(char *);void push_charstack(struct char_stack *,char);char pop_charstack(struct char_stack *);int is_charstackempty(struct char_stack *);void push_intstack(struct int_stack *,int);int pop_intstack(struct int_stack *);int is_intstackempty(struct int_stack *);void reverse_charstack(struct char_stack *);void reverse_intstack(struct int_stack *);int my_pow(int);int priority(char,char);int simple_express(int,char,int);int main(){ char * arr_ptr; int i; int value; while(1) { printf("请输入表达式:(输入q代表退出)\n"); getchar(); for(i=0; i<stdin->_bufsiz; ++i) if(*(stdin->_base+i) == 0x0A) break; fflush(stdin); arr_ptr = (char*) malloc(i*sizeof(char)+1); memcpy(arr_ptr, stdin->_base, i?i:1); *(arr_ptr+i) = '\0'; if('q'==arr_ptr[0]) goto quit; value=calval(arr_ptr); free(arr_ptr); if(tag) printf("表达式的值为%d\n",value); else printf("非法表达式!!\n"); } quit:free(arr_ptr); printf("退出程序!!"); system("pause"); return 0;}int calval(char * arr_ptr){ struct char_stack stack1,stack2; struct int_stack stack3; int i; int temp_int=0; int int_opnd1,int_opnd2; char char_oprat; int temp_sum; char temp_char; int sum; stack1.top=0; stack2.top=0; stack3.top=0; while('\0'!=*arr_ptr) { if(isdigit(*arr_ptr)) { for(i=0;isdigit(*arr_ptr);i++,arr_ptr++) ; while(i>0) { temp_int+=(*(arr_ptr-i)-'0')*my_pow(i-1); i--; } push_intstack(&stack3,temp_int); temp_int=0; } else if(IS_OPND(*arr_ptr)) { if(!is_charstackempty(&stack1)) { if(!priority(stack1.ch_arr[(stack1.top)-1],*arr_ptr)) { push_charstack(&stack2,stack1.ch_arr[(stack1.top)-1]); stack1.ch_arr[(stack1.top)-1]=*arr_ptr; } else { push_charstack(&stack1,*arr_ptr); } } else { push_charstack(&stack1,*arr_ptr); } arr_ptr++; } else if('('==*arr_ptr) { push_charstack(&stack1,*arr_ptr); arr_ptr++; } else if(')'==*arr_ptr) { while((!is_charstackempty(&stack1))&&((temp_char=pop_charstack(&stack1))!='(')) { push_charstack(&stack2,temp_char); } arr_ptr++; if(is_charstackempty(&stack1)&&('('!=temp_char)) return 0; } else return 0; } while(!is_charstackempty(&stack1)) { temp_char=pop_charstack(&stack1); if(('('==temp_char)||(')'==temp_char)) return 0; push_charstack(&stack2,temp_char); } reverse_charstack(&stack2); reverse_intstack(&stack3); while(!is_charstackempty(&stack2)&&!is_intstackempty(&stack3)) { int_opnd1=pop_intstack(&stack3); if(is_intstackempty(&stack3)) return 0; int_opnd2=pop_intstack(&stack3); char_oprat=pop_charstack(&stack2); temp_sum=simple_express(int_opnd1,char_oprat,int_opnd2); push_intstack(&stack3,temp_sum); } if(!is_charstackempty(&stack2)) return 0; if(is_intstackempty(&stack3)) return 0; sum=pop_intstack(&stack3); if(is_intstackempty(&stack3)) { tag=1; return sum; } else return 0;}void push_charstack(struct char_stack * stack_ptr,char ch){ if(stack_ptr->top<49) stack_ptr->ch_arr[(stack_ptr->top)++]=ch; else printf("charstack overflow!!\n");}char pop_charstack(struct char_stack * stack_ptr){ if(stack_ptr->top>0) return stack_ptr->ch_arr[--(stack_ptr->top)]; else printf("charstack empty!!\n");}int is_charstackempty(struct char_stack * stack_ptr){ return stack_ptr->top==0;}void push_intstack(struct int_stack * stack_ptr,int ch){ if(stack_ptr->top<49) stack_ptr->int_arr[(stack_ptr->top)++]=ch; else printf("intstack overflow!!\n");}int pop_intstack(struct int_stack * stack_ptr){ if(stack_ptr->top>0) return stack_ptr->int_arr[--(stack_ptr->top)]; else printf("intstack empty!!\n");}int is_intstackempty(struct int_stack * stack_ptr){ return stack_ptr->top==0;}void reverse_charstack(struct char_stack * stack_ptr){ struct char_stack temp_stack; char char_temp; temp_stack.top=0; while(!is_charstackempty(stack_ptr)) { char_temp=pop_charstack(stack_ptr); push_charstack(&temp_stack,char_temp); } memcpy(stack_ptr->ch_arr,temp_stack.ch_arr,temp_stack.top); stack_ptr->top=temp_stack.top;}void reverse_intstack(struct int_stack * stack_ptr){ struct int_stack temp_stack; int int_temp; temp_stack.top=0; while(!is_intstackempty(stack_ptr)) { int_temp=pop_intstack(stack_ptr); push_intstack(&temp_stack,int_temp); } memcpy(stack_ptr->int_arr,temp_stack.int_arr,temp_stack.top*sizeof(int)); stack_ptr->top=temp_stack.top;}int my_pow(int i) //计算10的次方{ //assert(i<0); if(i==0) return 1; int j=0,sum=1; while(j<i) { sum*=10; j++; } return sum;}int priority(char opnd1,char opnd2) //操作符优先级,如果opnd1优先级高于opnd2返回1,否则返回0{ if('('==opnd1) return 1; if(('*'==opnd1)||('/'==opnd1)) return 0; else { if(('+'==opnd2)||('-'==opnd2)) return 0; else return 1; }}int simple_express(int opnd1,char oprat,int opnd2){ if('+'==oprat) return (opnd1+opnd2); else if('-'==oprat) return (opnd1-opnd2); else if('*'==oprat) return (opnd1*opnd2); else if('/'==oprat) return (opnd1/opnd2); else printf("非法运算符!!");}
[解决办法]
不知道当初为什么写这段代码,不过记得当时写出来费不少劲呢,呵呵,现在看看,原来没判断右括号是否少的情况,只判断了是否多,不过应该不影响使用,当然了,完全用浮点数来算的,也别指望计算的精确性了
http://blog.csdn.net/zouyuncheng/article/details/7563135
[解决办法]
先学数据结构把。。否则很难写成的
或者学编译原理
如果实在想这么写很烦,用字符串读入,自己解析,还要考虑出错的情况
[解决办法]
/*---------------------------------------函数型计算器(VC++6.0,Win32 Console)程序由 yu_hua 于2007-07-27设计完成功能:目前提供了10多个常用数学函数: ⑴正弦sin ⑵余弦cos ⑶正切tan ⑷开平方sqrt ⑸反正弦arcsin ⑹反余弦arccos ⑺反正切arctan ⑻常用对数lg ⑼自然对数ln ⑽e指数exp ⑾乘幂函数∧用法:如果要求2的32次幂,可以打入2^32<回车>如果要求30度角的正切可键入tan(Pi/6)<回车>注意不能打入:tan(30)<Enter>如果要求1.23弧度的正弦,有几种方法都有效:sin(1.23)<Enter>sin 1.23 <Enter>sin1.23 <Enter>如果验证正余弦的平方和公式,可打入sin(1.23)^2+cos(1.23)^2 <Enter>或sin1.23^2+cos1.23^2 <Enter>此外两函数表达式连在一起,自动理解为相乘如:sin1.23cos0.77+cos1.23sin0.77就等价于sin(1.23)*cos(0.77)+cos(1.23)*sin(0.77)当然你还可以依据三角变换,再用sin(1.23+0.77)也即sin2验证一下。本计算器充分考虑了运算符的优先级因此诸如:2+3*4^2 实际上相当于:2+(3*(4*4))另外函数名前面如果是数字,那么自动认为二者相乘.同理,如果某数的右侧是左括号,则自动认为该数与括弧项之间隐含一乘号。如:3sin1.2^2+5cos2.1^2 相当于3*sin2(1.2)+5*cos2(2.1)又如:4(3-2(sqrt5-1)+ln2)+lg5 相当于4*(3-2*(√5 -1)+loge(2))+log10(5)此外,本计算器提供了圆周率 Pi键入字母时不区分大小写,以方便使用。----------------------------------------*/#include <iostream>#include <iomanip>#include <cstdlib>#include <cstring>#include <cctype>#include <cmath>#include <stdio.h>#include <string.h>#include <windows.h>using namespace std;const char Tab=0x9;const int DIGIT=1;const int MAXLEN=16384;char s[MAXLEN],*endss;int pcs=15;double fun(double x,char op[],int *iop) { while (op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号,如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter> switch (op[*iop-1]) { case 7: x=sin(x); (*iop)--;break; case 8: x=cos(x); (*iop)--;break; case 9: x=tan(x); (*iop)--;break; case 10: x=sqrt(x); (*iop)--;break; case 11: x=asin(x); (*iop)--;break; case 12: x=acos(x); (*iop)--;break; case 13: x=atan(x); (*iop)--;break; case 14: x=log10(x);(*iop)--;break; case 15: x=log(x); (*iop)--;break; case 16: x=exp(x); (*iop)--;break; } return x;}double calc(char *expr,char **addr) { static deep; //递归深度 static char *fname[]={ "sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp",NULL}; double ST[10]={0.0}; //数字栈 char op[10]={'+'}; //运算符栈 char c,*rexp,*pp,*pf; int ist=1,iop=1,last; if (!deep) { pp=pf=expr; do { c = *pp++; if (c!=' '&& c!=Tab) *pf++ = c; } while (c!='\0'); } pp=expr; if ((c=*pp)=='-'||c=='+') { op[0] = c; pp++; } last = !DIGIT; while ((c=*pp)!='\0') { if (c=='(') {//左圆括弧 deep++; ST[ist++]=calc(++pp,addr); deep--; ST[ist-1]=fun(ST[ist-1],op,&iop); pp = *addr; last = DIGIT; if (*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是:当右圆括弧的右恻为左圆括弧或函数名字时,默认其为乘法 op[iop++]='*'; last = !DIGIT; c = op[--iop]; goto operate ; } } else if (c==')') {//右圆括弧 pp++; break; } else if (isalpha(c)) { if (!strnicmp(pp,"Pi",2)) { if (last==DIGIT) { cout<< "π左侧遇)" <<endl;exit(1); } ST[ist++]=3.14159265358979323846264338328; ST[ist-1]=fun(ST[ist-1],op,&iop); pp += 2; last = DIGIT; if (!strnicmp(pp,"Pi",2)) { cout<< "两个π相连" <<endl;exit(2); } if (*pp=='(') { cout<< "π右侧遇(" <<endl;exit(3); } } else { for(int i=0; (pf=fname[i])!=NULL; i++) if (!strnicmp(pp,pf,strlen(pf)))break; if (pf!=NULL) { op[iop++] = 07+i; pp += strlen(pf); } else { cout<< "陌生函数名" <<endl;exit(4); } } } else if (c=='+'||c=='-'||c=='*'||c=='/'||c=='^') { char cc; if (last != DIGIT) { cout<< "运算符粘连" <<endl;exit(5); } pp++; if (c=='+'||c=='-') { do { cc = op[--iop]; --ist; switch (cc) { case '+': ST[ist-1] += ST[ist];break; case '-': ST[ist-1] -= ST[ist];break; case '*': ST[ist-1] *= ST[ist];break; case '/': ST[ist-1] /= ST[ist];break; case '^': ST[ist-1] = pow(ST[ist-1],ST[ist]);break; } } while (iop); op[iop++] = c; } else if (c=='*'||c=='/') {operate: cc = op[iop-1]; if (cc=='+'||cc=='-') { op[iop++] = c; } else { --ist; op[iop-1] = c; switch (cc) { case '*': ST[ist-1] *= ST[ist];break; case '/': ST[ist-1] /= ST[ist];break; case '^': ST[ist-1] = pow(ST[ist-1],ST[ist]);break; } } } else { cc = op[iop-1]; if (cc=='^') { cout<< "乘幂符连用" <<endl;exit(6); } op[iop++] = c; } last = !DIGIT; } else { if (last == DIGIT) { cout<< "两数字粘连" <<endl;exit(7); } ST[ist++]=strtod(pp,&rexp); ST[ist-1]=fun(ST[ist-1],op,&iop); if (pp == rexp) { cout<< "非法字符" <<endl;exit(8); } pp = rexp; last = DIGIT; if (*pp == '('||isalpha(*pp)) { op[iop++]='*'; last = !DIGIT; c = op[--iop]; goto operate ; } } } *addr=pp; if (iop>=ist) { cout<< "表达式有误" <<endl;exit(9); } while (iop) { --ist; switch (op[--iop]) { case '+': ST[ist-1] += ST[ist];break; case '-': ST[ist-1] -= ST[ist];break; case '*': ST[ist-1] *= ST[ist];break; case '/': ST[ist-1] /= ST[ist];break; case '^': ST[ist-1] = pow(ST[ist-1],ST[ist]);break; } } return ST[0];}int main(int argc,char **argv) { if (argc<=1) { if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页 cout << "计算函数表达式的值。"<<endl<<"支持(),+,-,*,/,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl; while (1) { cout << "请输入表达式:"; gets(s); if (s[0]==0) break;// cout << s <<"="; cout << setprecision(15) << calc(s,&endss) << endl; } } else { strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0; if (argc>=3) { pcs=atoi(argv[2]); if (pcs<0||15<pcs) pcs=15; printf("%.*lf\n",pcs,calc(s,&endss)); } else { printf("%.15lg\n",calc(s,&endss)); } } return 0;}
[解决办法]