軟體工程第二次作業——自動生成小學四則運算題目程式

今天你姓資了嗎發表於2020-11-02

作業說明

  1. 釋出一篇隨筆,使用markdown語法進行編輯
  2. 文字準確,樣式清晰
  3. 請在本次及之後的每次作業隨筆的最前面加上以下內容
  4. 部落格班級 填寫這份作業所在的部落格班級的連結
  5. 作業要求 填寫這份作業要求的連結
  6. 作業目標 填寫這份作業要達到哪些目標

程式碼如下:

這個作業屬於哪個課程 班級連結
這個作業要求在哪裡 班級連結
這個作業的目標 文中問題分析部分說明
學號 3180405308

題目要求

寫一個能自動生成小學四則運算題目的程式,然後在此基礎上擴充套件:

1)除了整數以外,還要支援真分數的四則運算,例如:1/6+1/8=7/24

2)程式要求能處理使用者的輸入,判斷對錯,累積分數

3)程式支援可以由使用者自行選擇加、減、乘、除運算

4)使用-n引數控制生成題目的個數,例如Myapp.exe -n 10,將生成10個題目

程式碼分析

結構體

//含有一個二元算數式的三個值以及一個標誌符的結構體
typedef struct{
    float x = 0,y = 0;    //x,y為給定的隨機數
    float r = 0;  //r為算數式結果
}Arithmetic;

選擇函式

//根據使用者選擇識別將要進行的四則運算型別
Arithmetic choose(Arithmetic n){
    int choose = 0;
    cout<<"請選擇您需要進行的四則運算型別\n"<<"1.加法\t2.減法\t3.乘法\t4.除法\n";
    cin>>choose;
    switch (choose) {
        case 1:
            n = Addition();
            break;
        case 2:
            n = Subtraction();
            break;
        case 3:
            n = Multiplication();
            break;
        case 4:
            n = Division();
            break;
            
        default:
            break;
    }
    
    return n;
}

轉譯使用者輸入結果

float conversion(string input){
    bool flag = false, sign = false;
    //flag標記使用者輸入中是否存在/號,有/號則true否則false
    //sign標記使用者輸入是否為負數,是負數則true否則false
    float a = 0, b = 0, result = 0;
    for (int i = 0; i<input.length(); i++) {
        if (input[i] != '/' && input[i] != '-') {
            int num = input[i]-'0'; //將char型轉換為int型
            if (!flag) {    //若果flag為false,則說明還未遇到/號
                a *= 10;    //a記錄/號前的數值
                a += num;
            } else {
                b *= 10;    //b記錄/號後的數值
                b += num;
            }
        } else if (input[i] == '/'){
            flag = true;
        } else {
            sign = true;
        }
    }
    
    if (flag && sign) { //既有/號,又是負值
        result = -a/b;
    } else if (flag && !sign){  //有/號,但為正值
        result = a/b;
    } else if (!flag && sign){  //沒有有/號,但為負值
        result = -a;
    } else {    //沒有有/號,且為正值
        result = a;
    }
    return result;
}

判斷對錯函式

bool judge(Arithmetic n){
    bool flag = false;  //flag用於記錄使用者輸入答案是否正確,正確return true,否則return false
    string input;
    cin>>input;
    if (n.r == conversion(input))
        flag = true;
    
    return flag;
}

Addition加法


Arithmetic Addition(){
    Arithmetic n;
    srand((unsigned)time(NULL));
    
    if (rand()%2 == 0) {//若為0則進行整數四則運算,若為1則進行真分數的四則運算
        n.x = rand()%size+1;
        n.y = rand()%size+1;
        n.r = n.x + n.y;
        printf("%.0f + %.0f = ?\n",n.x,n.y);
    } else {
        float a,b,c,d;
        a = rand()%size+1;
        b = rand()%size+1;
        c = rand()%size+1;
        d = rand()%size+1;
        if (a<b) {  //需要保證數值是真分數
            n.x = a/b;
        } else if (a==b){   //分子分母如果相同的話直接賦值為1
            n.x = 1;
        }else {     //需要保證數值是真分數
            n.x = b/a;
        }
        if (c<d) {  //需要保證數值是真分數
            n.y = c/d;
        } else if (c==d){   //分子分母如果相同的話直接賦值為1
            n.y = 1;
        }else {     //需要保證數值是真分數
            n.y = d/c;
        }
        n.r = n.x + n.y;
        
        if (n.r==0) {   //結果為0說明兩個真分數都是1/1
            printf("%.0f + %.0f = ?\n",n.x,n.y);
        } else if (n.x==1){ //僅有一個真分數,一個1/1
            printf("%.0f + %.0f/%.0f = ?\n",n.x,c<d?c:d,c>d?c:d);
        } else if (n.y==1){
            printf("%.0f/%.0f + %.0f = ?\n",a<b?a:b,a>b?a:b,n.y);
        } else {        //除去其他可能,僅剩下兩個數都是真分數的情況
            printf("%.0f/%.0f + %.0f/%.0f = ?\n",a<b?a:b,a>b?a:b,c<d?c:d,c>d?c:d);
        }
    }
    
    return n;
}

Subtraction減法

Arithmetic Subtraction(){
    Arithmetic n;
    srand((unsigned)time(NULL));
    
    if (rand()%2 == 0) {//若為偶數則進行整數四則運算,若為奇數則進行真分數的四則運算
        n.x = rand()%size+1;
        n.y = rand()%size+1;
        n.r = n.x - n.y;
        printf("%.0f - %.0f = ?\n",n.x,n.y);
    } else {
        float a,b,c,d;
        a = rand()%size+1;
        b = rand()%size+1;
        c = rand()%size+1;
        d = rand()%size+1;
        if (a<b) {
            n.x = a/b;
        } else if (a==b){
            n.x = 1;
        }else {
            n.x = b/a;
        }
        if (c<d) {
            n.y = c/d;
        } else if (c==d){
            n.y = 1;
        }else {
            n.y = d/c;
        }
        n.r = n.x - n.y;
        
        if (n.r==0) {
            printf("%.0f - %.0f = ?\n",n.x,n.y);
        } else if (n.x==1){
            printf("%.0f - %.0f/%.0f = ?\n",n.x,c<d?c:d,c>d?c:d);
        } else if (n.y==1){
            printf("%.0f/%.0f - %.0f = ?\n",a<b?a:b,a>b?a:b,n.y);
        } else {
            printf("%.0f/%.0f - %.0f/%.0f = ?\n",a<b?a:b,a>b?a:b,c<d?c:d,c>d?c:d);
        }
    }
    
    return n;
}

Multiplication乘法

Arithmetic Multiplication(){
    Arithmetic n;
    srand((unsigned)time(NULL));
    
    if (rand()%2 == 0) {//若為偶數則進行整數四則運算,若為奇數則進行真分數的四則運算
        n.x= rand()%size+1;
        n.y= rand()%size+1;
        n.r = n.x * n.y;
        printf("%.0f * %.0f = ?\n",n.x,n.y);
    } else {
        float a,b,c,d;
        a = rand()%size+1;
        b = rand()%size+1;
        c = rand()%size+1;
        d = rand()%size+1;
        if (a<b) {
            n.x = a/b;
        } else if (a==b){
            n.x = 1;
        }else {
            n.x = b/a;
        }
        if (c<d) {
            n.y = c/d;
        } else if (c==d){
            n.y = 1;
        }else {
            n.y = d/c;
        }
        n.r = n.x * n.y;
        
        if (n.r==0) {
            printf("%.0f * %.0f = ?\n",n.x,n.y);
        } else if (n.x==1){
            printf("%.0f * %.0f/%.0f = ?\n",n.x,c<d?c:d,c>d?c:d);
        } else if (n.y==1){
            printf("%.0f/%.0f * %.0f = ?\n",a<b?a:b,a>b?a:b,n.y);
        } else {
            printf("%.0f/%.0f * %.0f/%.0f = ?\n",a<b?a:b,a>b?a:b,c<d?c:d,c>d?c:d);
        }
    }
    
    return n;
}

Division除法

Arithmetic Division(){  //除法不需要考慮兩個整數的,沒有意義,直接兩個真分數的除法
    Arithmetic n;
    srand((unsigned)time(NULL));
    
    float a,b,c,d;
    a = rand()%size+1;
    b = rand()%size+1;
    c = rand()%size+1;
    d = rand()%size+1;
    if (a<b) {
        n.x = a/b;
    } else if (a==b){
        n.x = 1;
    }else {
        n.x = b/a;
    }
    if (c<d) {
        n.y = c/d;
    } else if (c==d){
        n.y = 1;
    }else {
        n.y = d/c;
    }
    n.r = n.x / n.y;
    
    if (n.r==0) {
        printf("%.0f / %.0f = ?\n",n.x,n.y);
    } else if (n.x==1){
        printf("%.0f / %.0f/%.0f = ?\n",n.x,c<d?c:d,c>d?c:d);
    } else if (n.y==1){
        printf("%.0f/%.0f / %.0f = ?\n",a<b?a:b,a>b?a:b,n.y);
    } else {
        printf("%.0f/%.0f / %.0f/%.0f = ?\n",a<b?a:b,a>b?a:b,c<d?c:d,c>d?c:d);
    }
    
    return n;
}

main函式

int main(int argc, const char * argv[]) {
    int score = 0, cnt = 0;
    
    printf("請設定題目數量\n");	//此處用於測試,原始碼部分,這段內容註釋掉
    scanf("%d",&cnt);

//    if (string(argv[1])=="-n") {      //在terminals或者command中執行的時候,引數順序存放在argv陣列中
//        string c = argv[2];
//        cnt = stoi(c);
//    }
    
    for (int i = 0; i<cnt; i++) {
        Arithmetic t;
        t = choose(t);
        if (judge(t) == true) {
            score+=10;
            cout<<"恭喜您回答正確!\n";
        } else {
            cout<<"很抱歉您的答案不正確,再想想哦~\n";
        }
    }
    printf("滿分為:%d  您的得分為:%d分\n",cnt*10,score);
    
    return 0;
}

執行截圖

  1. 在編譯器中執行
圖片名稱 圖片名稱
  1. 在terminals終端中執行
圖片名稱

個人小結

  1. 問題分析:真分數輸出問題

  2. 問題分析:真分數輸入問題

  3. 問題分析:浮點型資料精度值導致結果出錯

  4. 問題分析:在command或者terminals中給exe檔案或a.out檔案傳參問題

psp2.1 任務內容 計劃完成需要的時間(min) 實際完成需要的時間(min)
Planning 計劃 5 3
Estimate 估計這個任務需要多少時間,並規劃大致工作步驟 5 5
Development 開發 300 300
Analysis 需求分析(包括學習新技術) 15 45
Design Spec 生成設計文件 5 20
Design Review 設計複審 5 5
Coding Standard 程式碼規範 3 3
Design 具體設計 10 12
Coding 具體編碼 200 200
Code Review 程式碼複審 10 20
Test 測試(自我測試,修改程式碼,提交修改) 10 60
Reporting 報告 5 5
Test Report 測試報告 5 5
Size Measurement 計算工作量 20 30
Postmortem & Process Improvement Plan 事後總結,並提出過程改進計劃 20 20

原始碼

//
//  main.cpp
//  四則運算生成
//
//  Created by Chen on 2020/11/2.
//  Copyright © 2020 xxc. All rights reserved.
//

#include <iostream>
#include <string.h>
#define size 10
using namespace std;

//含有一個二元算數式的三個值
typedef struct{
    float x = 0,y = 0;    //x,y為給定的隨機數
    float r = 0;  //r為算數式結果
}Arithmetic;

Arithmetic choose(Arithmetic n);//選擇函式,根據使用者選擇 識別將要進行的四則運算型別
float conversion(string input);//使用者輸入轉換
bool judge(Arithmetic n);//結果判斷
Arithmetic Addition();//加法運算
Arithmetic Subtraction();//減法運算
Arithmetic Multiplication();//乘法運算
Arithmetic Division();//除法運算


int main(int argc, const char * argv[]) {
    int score = 0, cnt = 0;
    
//    printf("請設定題目數量\n");
//    scanf("%d",&cnt);

   if (string(argv[1])=="-n") {      //在terminals或者command中執行的時候,引數順序存放在argv陣列中
        string c = argv[2];
        cnt = stoi(c);
	}
    
    for (int i = 0; i<cnt; i++) {
        Arithmetic t;
        t = choose(t);
        if (judge(t) == true) {
            score+=10;
            cout<<"恭喜您回答正確!\n";
        } else {
            cout<<"很抱歉您的答案不正確,再想想哦~\n";
        }
    }
    printf("滿分為:%d  您的得分為:%d分\n",cnt*10,score);
    
    return 0;
}

//函式
//選擇函式,根據使用者選擇識別將要進行的四則運算型別
Arithmetic choose(Arithmetic n){
    int choose = 0;
    cout<<"請選擇您需要進行的四則運算型別\n"<<"1.加法\t2.減法\t3.乘法\t4.除法\n";
    cin>>choose;
    switch (choose) {
        case 1:
            n = Addition();
            break;
        case 2:
            n = Subtraction();
            break;
        case 3:
            n = Multiplication();
            break;
        case 4:
            n = Division();
            break;
            
        default:
            break;
    }
    
    return n;
}

//轉譯使用者輸入結果
float conversion(string input){
    bool flag = false, sign = false;
    //flag標記使用者輸入中是否存在/號,有/號則true否則false
    //sign標記使用者輸入是否為負數,是負數則true否則false
    float a = 0, b = 0, result = 0;
    for (int i = 0; i<input.length(); i++) {
        if (input[i] != '/' && input[i] != '-') {
            int num = input[i]-'0'; //將char型轉換為int型
            if (!flag) {    //若果flag為false,則說明還未遇到/號
                a *= 10;    //a記錄/號前的數值
                a += num;
            } else {
                b *= 10;    //b記錄/號後的數值
                b += num;
            }
        } else if (input[i] == '/'){
            flag = true;
        } else {
            sign = true;
        }
    }
    
    if (flag && sign) { //既有/號,又是負值
        result = -a/b;
    } else if (flag && !sign){  //有/號,但為正值
        result = a/b;
    } else if (!flag && sign){  //沒有有/號,但為負值
        result = -a;
    } else {    //沒有有/號,且為正值
        result = a;
    }
    return result;
}

//判斷對錯函式
bool judge(Arithmetic n){
    bool flag = false;  //flag用於記錄使用者輸入答案是否正確,正確return true,否則return false
    string input;
    cin>>input;
    if (n.r == conversion(input))
        flag = true;
    
    return flag;
}

//Addition加法
Arithmetic Addition(){
    Arithmetic n;
    srand((unsigned)time(NULL));
    
    if (rand()%2 == 0) {//若為0則進行整數四則運算,若為1則進行真分數的四則運算
        n.x = rand()%size+1;
        n.y = rand()%size+1;
        n.r = n.x + n.y;
        printf("%.0f + %.0f = ?\n",n.x,n.y);
    } else {
        float a,b,c,d;
        a = rand()%size+1;
        b = rand()%size+1;
        c = rand()%size+1;
        d = rand()%size+1;
        if (a<b) {  //需要保證數值是真分數
            n.x = a/b;
        } else if (a==b){   //分子分母如果相同的話直接賦值為1
            n.x = 1;
        }else {     //需要保證數值是真分數
            n.x = b/a;
        }
        if (c<d) {  //需要保證數值是真分數
            n.y = c/d;
        } else if (c==d){   //分子分母如果相同的話直接賦值為1
            n.y = 1;
        }else {     //需要保證數值是真分數
            n.y = d/c;
        }
        n.r = n.x + n.y;
        
        if (n.r==0) {   //結果為0說明兩個真分數都是1/1
            printf("%.0f + %.0f = ?\n",n.x,n.y);
        } else if (n.x==1){ //僅有一個真分數,一個1/1
            printf("%.0f + %.0f/%.0f = ?\n",n.x,c<d?c:d,c>d?c:d);
        } else if (n.y==1){
            printf("%.0f/%.0f + %.0f = ?\n",a<b?a:b,a>b?a:b,n.y);
        } else {        //除去其他可能,僅剩下兩個數都是真分數的情況
            printf("%.0f/%.0f + %.0f/%.0f = ?\n",a<b?a:b,a>b?a:b,c<d?c:d,c>d?c:d);
        }
    }
    
    return n;
}

//Subtraction減法
Arithmetic Subtraction(){
    Arithmetic n;
    srand((unsigned)time(NULL));
    
    if (rand()%2 == 0) {//若為偶數則進行整數四則運算,若為奇數則進行真分數的四則運算
        n.x = rand()%size+1;
        n.y = rand()%size+1;
        n.r = n.x - n.y;
        printf("%.0f - %.0f = ?\n",n.x,n.y);
    } else {
        float a,b,c,d;
        a = rand()%size+1;
        b = rand()%size+1;
        c = rand()%size+1;
        d = rand()%size+1;
        if (a<b) {
            n.x = a/b;
        } else if (a==b){
            n.x = 1;
        }else {
            n.x = b/a;
        }
        if (c<d) {
            n.y = c/d;
        } else if (c==d){
            n.y = 1;
        }else {
            n.y = d/c;
        }
        n.r = n.x - n.y;
        
        if (n.r==0) {
            printf("%.0f - %.0f = ?\n",n.x,n.y);
        } else if (n.x==1){
            printf("%.0f - %.0f/%.0f = ?\n",n.x,c<d?c:d,c>d?c:d);
        } else if (n.y==1){
            printf("%.0f/%.0f - %.0f = ?\n",a<b?a:b,a>b?a:b,n.y);
        } else {
            printf("%.0f/%.0f - %.0f/%.0f = ?\n",a<b?a:b,a>b?a:b,c<d?c:d,c>d?c:d);
        }
    }
    
    return n;
}

//Multiplication乘法
Arithmetic Multiplication(){
    Arithmetic n;
    srand((unsigned)time(NULL));
    
    if (rand()%2 == 0) {//若為偶數則進行整數四則運算,若為奇數則進行真分數的四則運算
        n.x= rand()%size+1;
        n.y= rand()%size+1;
        n.r = n.x * n.y;
        printf("%.0f * %.0f = ?\n",n.x,n.y);
    } else {
        float a,b,c,d;
        a = rand()%size+1;
        b = rand()%size+1;
        c = rand()%size+1;
        d = rand()%size+1;
        if (a<b) {
            n.x = a/b;
        } else if (a==b){
            n.x = 1;
        }else {
            n.x = b/a;
        }
        if (c<d) {
            n.y = c/d;
        } else if (c==d){
            n.y = 1;
        }else {
            n.y = d/c;
        }
        n.r = n.x * n.y;
        
        if (n.r==0) {
            printf("%.0f * %.0f = ?\n",n.x,n.y);
        } else if (n.x==1){
            printf("%.0f * %.0f/%.0f = ?\n",n.x,c<d?c:d,c>d?c:d);
        } else if (n.y==1){
            printf("%.0f/%.0f * %.0f = ?\n",a<b?a:b,a>b?a:b,n.y);
        } else {
            printf("%.0f/%.0f * %.0f/%.0f = ?\n",a<b?a:b,a>b?a:b,c<d?c:d,c>d?c:d);
        }
    }
    
    return n;
}

//Division除法
Arithmetic Division(){  //除法不需要考慮兩個整數的,沒有意義,直接兩個真分數的除法
    Arithmetic n;
    srand((unsigned)time(NULL));
    
    float a,b,c,d;
    a = rand()%size+1;
    b = rand()%size+1;
    c = rand()%size+1;
    d = rand()%size+1;
    if (a<b) {
        n.x = a/b;
    } else if (a==b){
        n.x = 1;
    }else {
        n.x = b/a;
    }
    if (c<d) {
        n.y = c/d;
    } else if (c==d){
        n.y = 1;
    }else {
        n.y = d/c;
    }
    n.r = n.x / n.y;
    
    if (n.r==0) {
        printf("%.0f / %.0f = ?\n",n.x,n.y);
    } else if (n.x==1){
        printf("%.0f / %.0f/%.0f = ?\n",n.x,c<d?c:d,c>d?c:d);
    } else if (n.y==1){
        printf("%.0f/%.0f / %.0f = ?\n",a<b?a:b,a>b?a:b,n.y);
    } else {
        printf("%.0f/%.0f / %.0f/%.0f = ?\n",a<b?a:b,a>b?a:b,c<d?c:d,c>d?c:d);
    }
    
    return n;
}

相關文章