第一次作业--四则运算

 

需求分析:

 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

 

posted @ 2017-09-23 17:08  Missy_by  阅读(339)  评论(2编辑  收藏  举报