zoukankan      html  css  js  c++  java
  • 第一次作业四则运算

    需求分析:

     1.获取生成题目的数量;(该数值必须给定,否则程序出错)

     2.控制生成四则运算中最大值的范围;(该数值必须给定,否则程序出错)

     3.生成的题目中存在心如e1/e2的字表达式的姓氏,其结果需要化为真分数,其中真分数在输入输出时采用如下格式,真分数五分之三表示为3/5,真分数二又八分之三表示为2’3/8;

     4.每道题目中出现的运算符个数不超过3个。

     5.程序生成的题目不能重复,即任何两道题目不能通过有限次交换变换为同一道题目;

     6. 程序应能支持一万道题目的生成。

     7. 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计

    设计思路:

        1. 程序的主要实现功能部分在于随机生成运算符不超过3个的n道题目,运算式通过逆波兰计算出结果,生成的答案如果不是整数,将化成真分数表示;

        2. 运算式的个数用count变量保存,至少有两个,如果随机产生count>2,之前的运算式变成其中一个操作数,即a+b,a->c+d;

        3. 通过逆波兰将运算式化成后缀表达式,计算后缀表达式,将结果保存;

        4. 如果得到不是整数的结果,需要化成分数的形式,由于结果是float类型,分子分母同时乘1000000,通过MaxY求得最大公约数,如果分子比分母大,分子除分母后强制转换int后         保存,分子c=c-num*d,然后就可以输出形如2’3/8的形式。

        5. 用两个数组保存输入的答案跟正确答案,然后比较,正确计数器+1,并保存题号,错误同理;

    实现语言:C++

    代码说明:

         1.主要界面

    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    #include <string.h>
    #include<dos.h>
    #include "takeTest.h"
    int main() {
        int n,a,i,max,repeat,right=0,wrong=0;
        double percent;
    //    float result[100]={0};
        // printf("%f",getResult());
        printf("请输入测试的题目数:");
        scanf("%d",&n);
        printf("请输入测试的最大数:");
        scanf("%d",&max);
        float ans[n],result[n];
        int t[n],f[n];
        printf("\n---随机生成%d道题目:\n",n);
        for(i=0; i<n; i++) {
            result[i]=takeTest(max,i);
            //  right=right+a;
        }
    //   printf("%f",result[i]);
        printf("\n---开始答题:\n");
        for(int i=0; i<n; i++) {
            printf("第(%d)题:",i+1);
            scanf("%f",&ans[i]);
        }
        printf("\n---正确答案:\n");
        for(int i=0; i<n; i++) {
            printf("(%d)小数:%g   真分数: ",i+1,result[i]);
            numden(result[i]);
        }
        for(int i=0,j=0,k=0; i<n; i++) {
            if(ans[i]==result[i]) {
                right++;
                t[j]=i+1;
                j++;
            } else {
                wrong++;
                f[k]=i+1;
                k++;
            }
        }
        printf("\n做对的题目有%d题,题号是:",right);
        for(int i=0; i<right; i++) {
            printf("%d、",t[i]);
        }
        printf("\n做错的题目有%d题,题号是:",wrong);
        for(int i=0; i<wrong; i++) {
            printf("%d、",f[i]);
        }
        printf("\n重复的题目有  题",repeat);
    }

        2 、随机生成n道题目

    #include<fstream>
    #include<iostream>
    #include<stdlib.h>
    #include<iomanip>
    #include<time.h>
    #include<cmath>
    #include<string>
    #include<stdio.h>
    #include "getResult.h"
    #include "safe.h"
    using namespace std;
    #define random() (rand()%100000)
    char create_symbol(int n) {
        int n1,j;
        char symbol[1];
        j=random()%4;
        if(j==0) symbol[0]='+';
        else if(j==1) symbol[0]='-';
        else if(j==2) symbol[0]='*';
        else symbol[0]='/';
        return symbol[0];
    }
    string int_string(int number) {
        int temp=abs(number);
        char str[200];
        itoa(temp,str,10);
        string str_=str;
        return str_;
    }
    string combination(string str1,string str2,char k) {
        string equation;
        equation=str1+k+str2;
        return equation;
    }
    float takeTest(int max ,int i) {
        int num1,num2,count,n,change,range,j;
        string str_num1,str_num2,temp,exp;
        range=max;
        char symbol;
        ofstream fout;
        num1=random()%range+1;
        num2=random()%range+1;
        count=random()%3+2;// 设置运算式的长度
        symbol=create_symbol(n);
        str_num1=int_string(num1);
        str_num2=int_string(num2);
        exp=combination(str_num1,str_num2,symbol);
        if(count>2) {
            for(count; count>2; count--) {
                symbol=create_symbol(n);
                str_num1=exp;
                change=random()%2;
                if(change==0) {
                    str_num1='('+str_num1+')';
                }
                symbol=create_symbol(n);
                num2=random()%range+1;
                str_num2=int_string(num2);
                change=random()%2;
                if(change==0) {
                    temp=str_num1;
                    str_num1=str_num2;
                    str_num2=temp;
                }
                exp=combination(str_num1,str_num2,symbol);
            }
        }
        cout<<""<<i+1<<"题:"<<exp<<"="<<endl;
        // printf("%f",getResult(exp));
        return getResult(exp);
    
    }

    3. 通过逆波兰将运算式转化为后缀表达式,并且得出结果

    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>
    #include <iostream>
    #include "numden.h"
    #include <cstring>
    using namespace std;
    char str[100];
    char ex[100];
    /*存储后缀表达式*/
    void trans() { /*将算术表达式转化为后缀表达式*/
        int max=100;
        char stack[max];
        char ch;
        int sum,i,j,t,top=0;
        i=0; /*获取用户输入的表达式*/
    //    do {
    //        i++;
    //        scanf("%c",&str[i]);
    //    } while(str[i]!='#' && i!=max);
    //   strcpy(str, "(5+15)/10#");
        sum=i;
        t=1;
        i=0;
        ch=str[i];
        i++;
        while(ch!='#') {
            switch(ch) {
                case '(':
                    top++;
                    stack[top]=ch;
                    break;
                case ')':
                    while(stack[top]!='(') {
                        ex[t]=stack[top];
                        top--;
                        t++;
                    }
                    top--;
                    break;
                case '+':
                case '-':
                    while(top!=0&&stack[top]!='(') {
                        ex[t]=stack[top];
                        top--;
                        t++;
                    }
                    top++;
                    stack[top]=ch;
                    break;
                case '*':
                case '/':
                    while(stack[top]=='*'||stack[top]=='/') {
                        ex[t]=stack[top];
                        top--;
                        t++;
                    }
                    top++;
                    stack[top]=ch;
                    break;
                case ' ':
                    break;
                default:
                    while(ch>='0'&&ch<='9') {
                        ex[t]=ch;
                        t++;
                        ch=str[i];
                        i++;
                    }
                    i--;
                    ex[t]='&';
                    t++;
            }
            ch=str[i];
            i++;
        }
        while(top!=0) {
            ex[t]=stack[top];
            t++;
            top--;
        }
        ex[t]='#';
    }
    /*计算后缀表达式的值*/
    float com() {
        int max=100;
        float stack[max],d;
        char ch;
        int t=1,top=0;
        ch=ex[t];
        t++;
        while(ch!='#') {
            switch(ch) {
                case '+':
                    stack[top-1]=stack[top-1]+stack[top];
                    top--;
                    break;
                case '-':
                    stack[top-1]=stack[top-1]-stack[top];
                    top--;
                    break;
                case '*':
                    stack[top-1]=stack[top-1]*stack[top];
                    top--;
                    break;
                case '/':
                    if(stack[top]!=0)
                        stack[top-1]=stack[top-1]/stack[top];
                    else {
                        printf("\n\t除零错误!\n");
                        exit(0); /*异常退出*/
                    }
                    top--;
                    break;
                default:
                    d=0;
                    while(ch>='0'&&ch<='9') {
                        d=10*d+ch-'0';
                        ch=ex[t];
                        t++;
                    }
                    top++;
                    stack[top]=d;
            }
            ch=ex[t];
            t++;
        }
        return  stack[top];
    }
    float getResult(string s) {
        strncpy(str,s.c_str(),s.length());
        str[s.length()] ='#';
        trans();
        for(int i=0; i<2; i++)
            printf("  ",ex[i]);
     //   numden(com());
        return com();
    }

    4.  得到的不是整数的结果需要化成真分数的形式

    #include<stdio.h>
    #include<ctype.h>
    #include<math.h>
    int MaxY(int a,int b) ;
    void numden(float m) {
        int a,b=1000000,num;
        a=(int)(m*1000000);
        int max=MaxY(a,b);
        int c,d;
        c=a/max;
        d=b/max;
        if(m==(int)m) {
            printf("%d\n",int(m));
        } else if(abs(c)>d) {
            num=(int)(c/d);
            c=c-num*d;
            printf("%d'%d/%d\n",num,abs(c),d);
        } else if(d==1) {
            printf("%d\n",c);
        } else  printf("%d/%d\n",c,d);
    }
    int MaxY(int a,int b) {
        int min, max;
        int r;
        max=a>b?a:b;
        min=a<b?a:b;
        if(max%min==0)
            return abs(min);
        while(max%min!=0) {
            r=max%min;
            max=min;
            min=r;
        }
        return abs(min);
    }

    运行结果:

    PSP表格:

     PSP2.1 Personal Software Process Stages  estimated time  Actual time
     Planning  计划  10  10
     · Estimate  估计这个任务需要多少时间 10  20
     Development  开发  20  30
     · Analysis  需求分析 (包括学习新技术)  60  100
     · Design Spec  生成设计文档  20  20
     · Design Review  设计复审  10  30
     · Coding Standard  代码规范  10  10
     · Design  具体设计 30  40
     · Coding  具体编码  300  400
     · Code Review  代码复审  60  50
     · Test  测试(自我测试,修改代码,提交修改)  10  10
     Reporting  报告  60  100
     ·  测试报告  10  10
     ·  计算工作量    
     ·  并提出过程改进计划    

    不足:

    没有实现题目查重的功能;

    代码仓库地址:

    https://coding.net/u/Missyby/p/program1

  • 相关阅读:
    eclipse/myeclipse介绍
    HDU 5802 Windows 10
    LaTeX test
    数据结构2 静态区间第K大/第K小
    数据结构1 「在线段树中查询一个区间的复杂度为 $O(log N)$」的证明
    HDU 1007 Quoit Design
    HDU 5761 Rower Bo
    hihocoder #1341 Constraint Checker
    HDU #5733 tetrahedron
    hihocoder #1327
  • 原文地址:https://www.cnblogs.com/bymissy/p/7581776.html
Copyright © 2011-2022 走看看