首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

求实现直接输入表达式回车的计算器算法。多谢

2012-08-31 
求实现直接输入表达式回车的计算器算法。。!谢谢!我想做一个计算器程序,直接输入比如 1+2然后回车出结果。可

求实现直接输入表达式回车的计算器算法。。!谢谢!
我想做一个计算器程序,直接输入比如 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空间外加字符串解析,很简单的 ……
[解决办法]

C/C++ code
#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
[解决办法]
先学数据结构把。。否则很难写成的

或者学编译原理

如果实在想这么写很烦,用字符串读入,自己解析,还要考虑出错的情况
[解决办法]

C/C++ code
/*---------------------------------------函数型计算器(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;} 


[解决办法]

探讨

谢谢你们 3 4 楼 关于用scanf("%f%c%f",&amp;x,&amp;op,&amp;y 这样我也想到了。但是输入的时候肯定要有分隔符的 而不是直接输入1+2然后回车出答案。。。。 不过也谢谢了!

6楼的高人的代码我完全看不懂 不过也谢谢你了 这么辛苦写这么多。。。。。

额,难道是我现在学习的东西还不多,目前的知识完全做不出来的原因么?

[解决办法]
是 scanf(" %lf %c %lf", &d1, &c, &d2);

而不是scanf("%lf%c%lf", &d1, &c, &d2);

热点排行