四则运算

1.作业规范要求

博客編輯 https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18
作业要求 https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18/homework/11377
作业目标 写一个能自动生成小学四则运算题目的程序,然后在此基础上扩展:
1)除了整数以外,还要支持真分数的四则运算,例如:1/6+1/8=7/24
2)程序要求能处理用户的输入,判断对错,累积分数
3)程序支持可以由用户自行选择加、减、乘、除运算
4)使用-n参数控制生成题目的个数,例如Myapp.exe -n 10,将生成10个题目
学号 3180701234

2.题目要求

写一个能自动生成小学四则运算题目的程序,然后在此基础上扩展:

1)除了整数以外,还要支持真分数的四则运算,例如:1/6+1/8=7/24

2)程序要求能处理用户的输入,判断对错,累积分数

3)程序支持可以由用户自行选择加、减、乘、除运算

4)使用-n参数控制生成题目的个数,例如Myapp.exe -n 10,将生成10个题目

3.代码提交

1.中缀转后缀并计算

void qiuzhi(char *bds)//中转后并求值 
{  FILE *fp;
    int i = 0;
    stack *ysf = (stack*)malloc(sizeof(stack));//为表达式开辟一个stack
    ysf->size = 0;
    float num[50];//用于求值的数组
    int numpos = 0;//用于求值的数组位置,因使用较少为提高效率选择数组
    printf("后缀表达式为:");//附加
    while (bds[i] != '=')
    {
        if (bds[i] == '\0')
        {
            printf("表达式应该有=");
            return;
        }
        if (bds[i] <= '9'&&bds[i] >= '0')//转化数字
        {
            num[++numpos] = 0;
            while (bds[i] <= '9'&&bds[i] >= '0')
            {
                num[numpos] *= 10;
                num[numpos] += (bds[i] - '0');
                ++i;
            }
            if (bds[i] == '.')
            {
                double f_car = 0.1;//定义基数
                ++i;
                while (bds[i] <= '9'&&bds[i] >= '0')
                {
                    num[numpos] += ((bds[i] - '0')*f_car);
                    f_car *= 0.1;
                    ++i;
                }
            }//计算小数点
        }
        else
        {
            if (empty(ysf))
                push(ysf, bds[i]);
            else
            {
                if (bds[i] == '(')
                    push(ysf, bds[i]);
                else if (bds[i] == ')')
                {
                    while (top(ysf) != '(')
                    {
                        reckon(&num[numpos - 1], num[numpos], top(ysf));
                        printf("%c", pop(ysf));
                        --numpos;
                    }
                    pop(ysf);//弹出右括号
                }
                else
                {
                    while (compare(bds[i])<=compare(top(ysf)))
                    {
                        reckon(&num[numpos - 1], num[numpos], top(ysf));
                        printf("%c", pop(ysf));
                        --numpos;
                    }
                    push(ysf, bds[i]);
                }
            }
            ++i;
        }
    }
    while (!empty(ysf))
    {
        reckon(&num[numpos - 1], num[numpos], top(ysf));
        printf("%c", pop(ysf));
        --numpos;
    }
    fopen("/练习程序/answer.txt","w+");
      printf("\n运算结果为:%.2f\n", num[1]);
        fprintf(fp,"%.2f\n",num[1]);

}
void reckon(float *a, float b, char c)//用于将两数字合并,前数传地址 
{    //表达式运算定义
    int t;
    if (c == '-')
    {    if(*a<b)//非负 
        {     t=*a;*a=b;b=t;}
        (*a)-=b;
    }
    else if (c == '+')
    {
        (*a) += b;
    }
    else if (c == '*')
    {
        (*a) *= b;
    }
    else     
        if(b!=0)
            (*a) /= b;
               
}

2.分数运算

void qiuzhi1(int a,int b,int c,int d,char s)
   {  int x,y,t,m;
       float p,q;//中间数 
       int re1,re2,u;//分子分母 
       
    x=getGcd(a,b);//对a,b约分
    a/=x;
    b/=x;
    y=getGcd(c,d);//对c,d约分
    c/=y;
    d/=y;
   FILE *fp=fopen("/练习程序/subject.txt","w+");//读写文件位置
   
   switch(s)//选取运算符
   {
   case '+':
     re1=a*d+c*b;
     re2=b*d;
     t=getGcd(re1,re2);
     re1/=t;
     re2/=t;
     printf("%d/%d + %d/%d=%d/%d\n",a,b,c,d,re1,re2);
     fprintf(fp, "%d/%d + %d/%d=%d/%d\n",a,b,c,d,re1,re2);
     break;
   case '-':
       p=a/b;
       q=c/d;
       if(p<q)//判断结果不为负
       {
           u=a;
           a=c;
           c=u;
           u=b;
           b=d;
           d=u;
       }
       re1=a*d-c*b;//结果分子的运算
        re2=b*d;
        t=getGcd(re1,re2);//约分
     re1/=t;
     re2/=t;
        printf("%d/%d - %d/%d=%d/%d\n",a,b,c,d,re1,re2);
        fprintf(fp, "%d/%d - %d/%d=%d/%d\n",a,b,c,d,re1,re2);

     break;
   case '*':
       re1=a*c;
       re2=b*d;
        t=getGcd(re1,re2);
     re1/=t;
     re2/=t;
     if(a==0||c==0)//有分数为0时
        {
        printf("%d/%d * %d/%d=0",a,b,c,d);
         fprintf(fp, "%d/%d * %d/%d=0",a,b,c,d);
     }
     else
        printf("%d/%d * %d/%d=%d/%d\n",a,b,c,d,re1,re2);
        fprintf(fp, "%d/%d * %d/%d=%d/%d\n",a,b,c,d,re1,re2);
        
     break;
   case '/':
       
       re1=a*d;
       re2=b*c;
        t=getGcd(re1,re2);
     re1/=t;
     re2/=t;
     if(a==0)
        {printf("%d/%d / %d/%d=0",a,b,c,d);//结果为0
        fprintf(fp, "%d/%d / %d/%d=0",a,b,c,d);
    }
     else{
        printf("%d/%d / %d/%d=%d/%d\n",a,b,c,d,re1,re2);
        fprintf(fp, "%d/%d / %d/%d=%d/%d\n",a,b,c,d,re1,re2);
          }
        
    }

}

3.读取题目信息

void creat1(int num,int r)
{
    char a[]={'+','-','*','/'};
    int X,c,t;
    int i,j,b,count;
    int x,y,x1,y1,z,e;
    int n=sizeof(a);
    srand(time(NULL));
    
    FILE *fp = NULL;//打开文件 
     fp = fopen("/练习程序/test.txt", "w+");
     
    for(j=0;j<num;j++)
    { x=rand()%r;
      y=rand()%r;
      x1=rand()%r;
      y1=rand()%r;
      z=rand()%r;
      X=rand()%4;
      i=rand()%n;
      b=rand()%n;
      c=rand()%n;
      x!=y;
      switch(X)//控制符号数 
        {    case 0:
             printf("第%d题:%d%c%d= \n",j+1,x,a[i],y);
            fprintf(fp, "%d%c%d= \n",x,a[i],y);
            
            break;
            case 1:
                printf("第%d题:%d%c%d%c%d=  \n",j+1,x,a[i],y,a[b],z);
                fprintf(fp, "%d%c%d%c%d=  \n",x,a[i],y,a[b],z);
                break;
            case 2:
                fprintf(fp, "%d%c%d%c%d%c%d= \n",x,a[i],y,a[b],x1,a[c],z);
                printf("第%d题:%d%c%d%c%d%c%d= \n",j+1,x,a[i],y,a[b],x1,a[c],z);
                break;
            
        }
        
    }
    fclose(fp);
    
}
void save()
{    stack *p;
    char bds[50];
    FILE *fx;//读取文件 
    int line,i;
    if((fx = fopen("/练习程序/test.txt","r")) == NULL)
     {
     printf("error\n");
     exit (1) ;
     }    
     char buf[1024];
     for (i = 0; i < 1024; i++) 
        {    while(fgets(bds,50,fx) != NULL)//输出文件
 {
         
             line = strlen(bds);
                 bds[line-1] = '\0';  /*去掉换行符*/
                     printf("%s  \n",bds);
                    qiuzhi(bds);
                     
         } 
         fclose (fx);
     } 
     } 

4.主函数

int main()

{        
        int num1,num2,m,n,r,type;
        printf("请选择输出类型:1or2");
        scanf("%d\n",&type);
        if(type==1)
        {    printf("请输入生成题目数量: ");
            scanf("%d \n",&num1);
            printf("请输入分子分母取值范围: ");
            scanf("%d %d",&m,&n);
            creat2(num,m,n);
         } 
         else if(type==2)
         {
          
            printf("请输入生成题目数量: ");
            scanf("%d \n",&num2);
            printf("请输入取值范围: ");
            scanf("%d %d",&r);
            creat1(num,r);
            save();//输出答案 
        }
        return 0;
}

4.测试结果

1.分数运算

2.文件生成

5.PSP表格

psp2.1 任务内容 计划完成需要的时间(min) 实际完成需要的时间(min)
Planning 计划 100 240
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 2000 3894
Development 开发 200 366
Analysis 需求分析(包括学习新技术) 180 1400
Design Spec 生成设计文档 100 150
Design Review 设计复审 60 120
Coding Standard 代码规范 60 70
Design 具体设计 20 35
Coding 具体编码 360 540
Code Review 代码复审 60 164
Test 测试(自我测试,修改代码,提交修改) 120 180
Reporting 报告 60 80
Test Report 测试报告 20 30
Size Measurement 计算工作量 10 30
Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 40 60
合计 2290 4408

6.个人总结

从刚开始看到题目之后觉得只是很简单的题目很好写,并没有太大关注,等到自己实际操作时却感到不容易,学c语言学的最多也最熟悉就使用了c语言,在判断运算符优先级时,意识到要运用数据结构的内容时,又抽出了时间去复习。另外就是代码功能的实现问题,由于其中很多地方出现了一些问题,函数的参数不一,造成了很大的困扰,其次就是规范化,使得代码本身浪费了很多的时间,都是需要注意的地方,代码本身的函数与参数要规范好才能提高效率,这次的题目让我学到了很多东西,收获颇多

posted on 2020-11-09 00:11  卑微的小小灿  阅读(304)  评论(0)    收藏  举报

导航