回 帖 发 新 帖 刷新版面

主题:简单的计算器

题目三、简单的计算器
利用栈设计一个简单的一位数计算器,并用此进行简单表达式的求值。
要求:
1.    为简化操作,限定操作数只允许是一位整数0~9。
2.    运算符允许是+、-、*、/、^(乘方);并以输入分号’;’作为表达式的结束标志。运算符要考虑优先级,即+、-为最低,*、/为中等,^为最高
3.    表达式通过键盘一次输入。对非法字符的输入,应有错误信息提示,并等待重新输入。
4.    (选做)带左右括号的表达式计算,如:(2+3)*5-(7-4)
5.     对选择的数据存储方式说明选择的理由。
提示:
此题是栈的基本运算与串的综合应用。

帮帮我吧老师.  我的e_mail:zhuyanlin112@sina.com

回复列表 (共6个回复)

沙发

用什么语言写的都行吗

板凳


其实在将中缀变成后缀表达式时可以一边进行运算操作(即把运算符优先级高的取出来,然后从数字栈中连续取两个操作数与该运算符进行运算,再把所得结果压入数字栈),这样会使代码变得简短.我也做了一个计算器,但没有乘方的运算,代码80多行,暂时没有处理出错信息.

[color=C0C0C0][fly]担记得一定要自己想法写出代码,要注意这样是不能处理有负号的计算问题,必须先将字浮数组进行简单的处理.[/fly][/color]

3 楼


 #include<stdio.h>
#include<math.h>
#include<string.h>
typedef float DataType;
#include"LinStack.h"
 int first(char c) /*处理符号的优先级*/
{ int p;
  switch(c)
   {  case '=': case '#': p=-7; break;
      case '^': p=3; break;
      case '*': case '/': p=2; break;
      case '+': case '-': p=1; break;
      case '(': p=6; break; case '[': p=5; break; case '{': p=4; break;
      case ')': p=-6; break; case ']':p=-5; break;case '}': p=-4;break;
    } return(p);
}
 int tran(LSNode * heada,char * line)
 {int i=0,j,v,vt;DataType p,d,va,um=0.0;char uh[20]; uh[0]='#'; scanf("%s",line);
  if(line[0]=='-'){for(j=strlen(line);j>0;j--)line[j]=line[j-1];line[0]='0';}
   for(i=0;i<strlen(line);i++)
    {if((line[i]=='('||line[i]=='['||line[i]=='{')&&line[i+1]=='-')
       {for(j=strlen(line)+1;j>i+1;j--)line[j]=line[j-1];line[i+1]='0';}
     }i=0;j=0;
  while(line[i]!='\0')
   {va=0;
     if(line[i]<='9'&&line[i]>='0')
       {  while(line[i]<='9'&&line[i]>='0'){va=va*10+line[i]-'0';i++;}
          if(line[i]=='.')
          {i++;v=0;
            while(line[i]<='9'&&line[i]>='0')
            { va=va*10+line[i]-'0'; i++; v++;}
            for(vt=0;vt<v;vt++)va=va/10;
          }StackPush(heada,va);
       }
     else switch(line[i])
     {case'+':case'-':case'*':case'/':case'(':case ')':case'[':case']':case'{':case'}':
      case'=':case '#':case '^':if(first(line[i])>first(uh[j]))uh[++j]=line[i++];
                 else if(first(line[i])<=first(uh[j]))
                   {if(-first(line[i])==first(uh[j])){i++;j--;}
                   else if(first(uh[j])>3)uh[++j]=line[i++];
                   else if(StackNotEmpty(heada)!=0)
                       { StackPop(heada,&d);
                           if(StackNotEmpty(heada)==0)
                             {if(uh[j]!='#')printf("Gramer error!\n");else printf("  %5.4f\n",um);return 1;}
                           else{ StackPop(heada,&p);
                                  switch(uh[j--])
                                   {case '+':um=p+d;break; case '-':um=p-d;break; case '*':um=p*d;break;
                                    case '/':if(d==0){printf("Gramer error!\n");return -1;}else um=p/d;break;
                                    case '^':um=pow(p,d);break;
                                   }StackPush(heada,um);
                       }        }
                     }break;
       default:printf("illegal character!\n"); return -1;
     }
    }
 }
 void main()
 {LSNode *hea;char str[100],c='n';StackInitiate(&hea);clrscr();/*清屏函数*/
    printf("Welcome to use simple calculator\n(Any key to continue.)Input data to work:\n");
   while (1)
     {tran(hea,str);
       getchar(); textbackground(2);
     cprintf("Exit or not!(Y?):  ");
       cscanf("%c",&c);
       if(c=='y'||c=='Y')break;
     }
   }

4 楼

如果要用两个不同的堆栈,如何定义???

5 楼

你看看这个行不,我刚刚交给老师的作业,也正在学习数据结构,欢迎交流....


#include <stdio.h>
#include <stdlib.h>
#define stack_size 100
#define stack_increase 10

typedef struct{           //定义字符栈,存放运算符
    char *base;
    char *top;
    int stacksize;
}Sqcharstack;

int Initcharstack(Sqcharstack &s){
    s.base=(char *)malloc(stack_size*sizeof(char));
    if(!s.base){
        printf("存储分配失败\n");
        exit(0);
    }
    s.top=s.base;
    s.stacksize=stack_size;
    return 1;
}

char Getchartop(Sqcharstack s){
    if(s.base==s.top){
        printf("此栈为空\n");
        return NULL;
    }
    
    return *(s.top-1);
}

int Pushchar(Sqcharstack &s,char e){
    if(s.top-s.base>=s.stacksize){
        s.base=(char *)realloc(s.base,(s.stacksize+stack_increase)*sizeof(char));
        if(!s.base){
            printf("存储分配失败\n");
            exit(0);
        }
        s.top=s.base+s.stacksize;
        s.stacksize+=stack_increase;
    }
    *s.top++=e;
    return 1;
}

int Popchar(Sqcharstack &s,char &e){
    if(s.base==s.top){
        printf("此栈为空\n");
        return 0;
    }
    e=*(--s.top);
    return 1;
}

int charStackEmpty(Sqcharstack s){
    if(s.base==s.top)return 1;
    else return 0;
}


//定义符点栈,存放运算数
typedef struct{
    float *base;
    float *top;
    int stacksize;
}Sqfloatstack;

int Initfloatstack(Sqfloatstack &s){
    s.base=(float *)malloc(stack_size*sizeof(float));
    if(!s.base){
        printf("存储分配失败\n");
        exit(0);
    }
    s.top=s.base;
    s.stacksize=stack_size;
    return 1;
}

float Getfloattop(Sqfloatstack s){
    if(s.base==s.top){
        printf("此栈为空\n");
        return 0;
    }
    
    return *(s.top-1);
}

int Pushfloat(Sqfloatstack &s,float e){
    if(s.top-s.base>=s.stacksize){
        s.base=(float *)realloc(s.base,(s.stacksize+stack_increase)*sizeof(float));
        if(!s.base){
            printf("存储分配失败\n");
            exit(0);
        }
        s.top=s.base+s.stacksize;
        s.stacksize+=stack_increase;
    }
    *s.top++=e;
    return 1;
}

int Popfloat(Sqfloatstack &s,float &e){
    if(s.base==s.top){
        printf("此栈为空\n");
        return 0;
    }
    e=*(--s.top);
    return 1;
}

int floatStackEmpty(Sqfloatstack s){
    if(s.base==s.top)return 1;
    else return 0;
}



int IsOperate(char c){       //判断是否是运算符
    if(c>='0'&&c<='9'||c=='.')return 0;
    else return 1;
}

float Operate(float a,char c,float b){
    switch(c){
    case '+':return a+b;break;
    case '-':return a-b;break;
    case '*':return a*b;break;
    case '/':return a/b;break;
    default:return 0;
    }
}

char Precede(char a,char b){ 
    switch(a){
    case '+':if(b=='*'||b=='/'||b=='(')return '<';
        else return '>';
        break;
    case '-':if(b=='*'||b=='/'||b=='(')return '<';
        else return '>';
        break;
    case '*':if(b=='(')return '<';
        else return '>';
        break;
    case '/':if(b=='(')return '<';
        else return '>';
        break;
    case '(':if(b==')')return '=';
        else return '<';
        break;
    case ')':return '>';
        break;
    case '=':if(b=='=')return '=';
        else return '<';
        break;
    default:return NULL;
    }
}

下一页面

6 楼


float Square(int a,int b){     //定义函数a^b,求次方
    double e=1,i;
    if(b>=0){
        for(i=0;i<b;i++){
        e*=a;
        }
        return (float)e;
    }
    else {
        for(i=0;i<-b;i++){
            e*=1.0/a;
        }
    return (float)e;
    }
}


int Iscount(char a[],int n){      //判断是否有小数点,返回小数点出现的位置
    int i;
    for(i=0;i<n;i++)
        if(a[i]=='.')return i;
        return 0;
}
float ToFloat(char a[],int n){   //把字符串转化为运算数
    float e=0;
    int i,j;
    j=Iscount(a,n);
    if(!j){
        for(i=0;i<n;i++){
        e+=Square(10,n-i-1)*(a[i]-'0');
        }
        return e;
    }
    else {
        for(i=0;i<j;i++){
            e+=Square(10,j-i-1)*(a[i]-'0');
        }
        for(i=j+1;i<n;i++){
            e+=Square(10,j-i)*(a[i]-'0');
        }
        return e;
    }
}

float Evaluate(){
    float a,b;
    char c,d;
    char s[16]={'\0'};        //作为缓存,存放运算数
    int i=0,turn=1;
    Sqcharstack Optr;
    Sqfloatstack Opnd;
    Initcharstack(Optr);
    Pushchar(Optr,'=');
    Initfloatstack(Opnd);
    c=getchar();
    while(c!='='||Getchartop(Optr)!='='){
        if(!IsOperate(c)){
            printf("AAAA>>>\n");
            turn=1;          //开关数,用于运算数入栈的开关
            s[i]=c;i++;
            c=getchar();
        }
        else {
            if(turn){ 
                Pushfloat(Opnd,ToFloat(s,i));
                i=0;
                turn=0;
            }
            switch(Precede(Getchartop(Optr),c)){
            case '<':Pushchar(Optr,c);
                c=getchar();
                break;
            case '=':Popchar(Optr,d);
                c=getchar();
                break;
            case '>':Popchar(Optr,d);
                Popfloat(Opnd,b);
                Popfloat(Opnd,a);
                Pushfloat(Opnd,Operate(a,d,b));
                break;
            }
        }
        
    }
    return Getfloattop(Opnd);
}


void main(){
    while(1){
    printf("请输入要计算的表达式,并以=结束:\n");
    printf("%.2f\n",Evaluate());
    //getchar();
    }

}

可以实现Float数据类型的运算,+,-,*,/,()运算.

我来回复

您尚未登录,请登录后再回复。点此登录或注册