软件工程第一周作业----小学生四则运算题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件工程第一周作业----小学生四则运算题相关的知识,希望对你有一定的参考价值。

程序的实现思路:

1、产生随机的数字和运算符,这是组成题目的零件。

数字分为整数和真分数。需要注意的是,为了保证正确,真分数应该要检查(1)分母不为0,(2)不能约分;同时为了避免计算结果是NaN或∞的情况,出于程序简单考虑,生成的整数都是正数。

运算符是简单的四则运算。

2、调用1中的功能,生成题目并计算结果。

在这里控制参与运算的数的个数是随机的、某个位置生成整数还是分数也是随机的。生成题目只需要简单的循环调用就可以了。

计算题目结果使用转化为运算符前缀式的方法。因为开始写的时候没有考虑加括号,直接用函数返回值压栈计算,再在这个基础上加括号就不方便了。这里也可以看见,一个函数最好只实现一个功能。

3、输入输出部分。

首先在屏幕打印一个简单的界面,然后循环地输出题目、输入结果、判断正误,最后给出统计结果。

 

以下是代码和结果:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <time.h>

#define limit 30           //分母的范围
int n;                     //运算数的范围

int FindCommonFactor(int p,int q)
{//返回最大公因数,默认2<=p<q;
    int i;                 //cursor
    int commonfactor=1;    //common factor

    for(i=2;i<=p;i++)
    {
        if(p%i==0 && q%i==0)
        {
            commonfactor*=i;
            p/=i;
            q/=i;
            i=2;
        }
    }
    return commonfactor;
}

float ProperFraction(char *s,int *i)
{//生成真分数存入s中,返回生成的数
    int p=0;         //分子
    int q=0;         //分母
    int cf;          //common fraction

    while(q==0 || q==1)                            //生成分母,分母不能是0或1
        q=rand()%limit;
    while(p==0)                                    //生成分子,分子<分母且p!=0
        p=rand()%q;

    if(p>1)                                        //格式化分数
    {
        cf=FindCommonFactor(p,q);
        p/=cf;
        q/=cf;
    }

    s[*i]=(;                                     //存入字符串
    (*i)++;
    if(p<10)
    {
        s[*i]=p+0;
        (*i)++;
    }
    else
    {
        s[*i]=p/10+0;
        (*i)++;
        s[*i]=p-(s[*i-1]-0)*10+0;
        (*i)++;
    }
    s[*i]=/;
    (*i)++;
    if(q<10)
    {
        s[*i]=q+0;
        (*i)++;
    }
    else
    {
        s[*i]=q/10+0;
        (*i)++;
        s[*i]=q-(s[*i-1]-0)*10+0;
        (*i)++;
    }
    s[*i]=);
    (*i)++;

    return (float)p/(float)q;
}

int Operator(char *s,int *i)
{//随机生成运算符,存入字符串,返回运算符编号
    int o=rand()%4;
    if(o==0) s[*i]=+;
    if(o==2) s[*i]=-;
    if(o==1) s[*i]=*;
    if(o==3) s[*i]=/;
    (*i)++;
    return o%2+1;
}

int Decimal(char *s,int* i)
{//随机生成整数,存入字符串,返回这个整数
    int num=0;                //生成数
    int tmp[10]={0};          //暂存数组
    int j=0;                  //cursor
    int substitude=0;         //替身

    while(num==0)
        num=rand()%n;
    substitude=num;
    while(num>0)                               //反序按位拆开
    {
        tmp[j]=num%10;
        num/=10;
        j++;
    }
    for(j--;j>=0;j--)                          //存入字符串
    {
        s[*i]=tmp[j]+0;
        (*i)++;
    }

    return substitude;
}

int Rank(char x,char y){
//x>y return1; x<=y return0;
    if(x==+ || x==-)
        x=1;
    if(x==* || x==/)
        x=2;
    if(x==#)
        x=0;

    if(y==+ || y==-)
        y=1;
    if(y==* || y==/)
        y=2;
    if(y==#)
        y=0;

    return (int)x>=(int)y;
}

float Question(char *s)
{//生成混合运算的字符串,返回计算结果
    int i=0;                 //cursor
    int j=0;                 //cursor
    int DorF;                //Decimal or Fraction
    int len=0;               //参与运算数的数量
    char stack[11]="#";      //符号栈,栈底压入最低级的符号
    float result[10]={0};    //结果栈
    int stacktop=1;          //符号栈顶
    int resulttop=0;         //结果栈顶
    float newnum=0;          //新生成数

    while(len<2)                                //参与运算的数至少有2个
        len=rand()%11;

    for(j=0;j<len-1;j++)
    {
        DorF=rand()%2;                          //随机生成数
        if(DorF)
            newnum=(float)Decimal(s,&i);
        else
            newnum=ProperFraction(s,&i);
        result[resulttop]=newnum;               //新数入栈
        resulttop++;
        Operator(s,&i);                         //生成运算符

        while(Rank(stack[stacktop-1],s[i-1]))   //弹出运算符并计算
        {
            switch((int)stack[stacktop-1])      //计算
            {
            case +:result[resulttop-2]+=result[resulttop-1];break;
            case -:result[resulttop-2]-=result[resulttop-1];break;
            case *:result[resulttop-2]*=result[resulttop-1];break;
            case /:result[resulttop-2]/=result[resulttop-1];break;
            }
             resulttop--;                       //修正结果栈
             stacktop--;                        //弹出运算符
        }
        stack[stacktop]=s[i-1];                 //新运算符入栈
        stacktop++;
    }
    DorF=rand()%2;
    if(DorF)
        newnum=(float)Decimal(s,&i);
    else
        newnum=ProperFraction(s,&i);
    result[resulttop]=newnum;                    //新数入栈
    resulttop++;
    while(stacktop>1)                            //剩下的计算
    {
        switch((int)stack[stacktop-1])           //计算
        {
            case +:result[resulttop-2]+=result[resulttop-1];break;
            case -:result[resulttop-2]-=result[resulttop-1];break;
            case *:result[resulttop-2]*=result[resulttop-1];break;
            case /:result[resulttop-2]/=result[resulttop-1];break;
        }
        resulttop--;                             //修正结果栈
        stacktop--;                              //弹出运算符
    }
    s[i]=0;                                      //题目结束

    return result[0];
}

float Trans(char *input){
    int i=0;           //cursor
    int p=0;           //分子
    int q=0;           //分母
    float num=0;       //数值
    int neg=0;         //负数

    if(input[0]==-)
    {
        neg=1;
        i++;
    }
    while(input[i]!=0 && input[i]!=/)
    {
        p*=10;
        p+=input[i]-0;
        i++;
    }
    if(input[i]==0)
        num=(float)p;
    else
    {
        i++;
        while(input[i]!=0)
        {
            q*=10;
            q+=input[i]-0;
            i++;
        }
        if(q<=0)
            num=0.0/0.0;
        else
        {
            if(p!=1 && FindCommonFactor(p,q)!=1)
                num=0.0/0.0;
            else
                num=(float)p/(float)q;
        }
    }
    return num;
}

int main(void) {
    int i=0;//cursor
    int questionnum=0;           //题目数量
    char question[100]={0};      //题目
    float result=0.0;            //题目结果
    char input[50]={0};          //输入结果
    int statistic=0;             //统计正确量
    float inputnum=0;            //输入数值

    for(;i<80;i++)                                   //界面
        printf("*");
    printf("\\n欢迎使用算式生成器!\\n");
    printf("\\n请输入要求:\\n");
    printf("参与计算数的范围:");
    scanf("%d",&n);
    printf("生成算式的数量:");
    scanf("%d",&questionnum);
    printf("\\n");

    for(i=0;i<questionnum;i++)                       //生成题目并判断输入是否正确
    {
        srand (time(NULL));
        result=Question(question);
        printf("%s = ",question);
        scanf("%s",input);
        inputnum=Trans(input);
        if(abs(inputnum-result)<=0.000005)
        {
            printf("correct!\\n\\n");
            statistic++;
        }
        else
            printf("error!\\n\\n");
    }

    printf("correct entry: %d\\n",statistic);         //统计结果
    printf("accuracy: %.2f%%\\n",((float)statistic*100)/questionnum);
    return 0;
}

技术分享

 

以上是关于软件工程第一周作业----小学生四则运算题的主要内容,如果未能解决你的问题,请参考以下文章

第一周作业——小学四则运算题

软件工程第一周作业----个人项目总结

软件工程第一次作业

现代软件工程_第一周练习_第1题_万世想

软件工程第一次作业,小学生四则运算的出题程序

第一次作业