四則運算—基於控制台

来源:https://www.cnblogs.com/lianjiaming/archive/2018/03/30/8678436.html
-Advertisement-
Play Games

四則運算題目自動生成——基於控制台(java) "個人作業——四則運算題目生成程式(基於控制台)" 項目已提交到碼雲: "UMLProject" 需求分析: 關於輸入、根據提示依次輸入: 數字範圍(樣例:10) 題目數量(樣例:10) 生成的題目: 如果存在形如e1 ÷ e2的子表達式,那麼其結果應 ...


四則運算題目自動生成——基於控制台(java)


個人作業——四則運算題目生成程式(基於控制台)

項目已提交到碼雲:UMLProject

需求分析:

  • 關於輸入、根據提示依次輸入:
    • 數字範圍(樣例:10)
    • 題目數量(樣例:10)
  • 生成的題目:
    • 如果存在形如e1 ÷ e2的子表達式,那麼其結果應是真分數。
    • 每道題目中出現的運算符個數不超過3個。
    • 整數表示為1,真分數表示為1/2,假分數表示為2’1/2
  • 程式支持:
    • 一萬道題目生成
    • 生成題目的同時計算出答案,分別保存本地txt文件。
    • 題目進行查重,去除重覆。
    • 對個人答案的批改

功能設計:

控制台實現,功能相對簡單,實現按要求生成題目,根據用戶選擇進行是否批改答案。並顯示批改結果。


設計實現

1. 生成題目問題:

通過RandomQuestion類最終生成題目,RandomNum類和RandomSign類分別生成操作數和運算符。

RandomSign類:

public RandomSign(){//隨機生成符號
        int random_sign;
        random_sign = (int)(Math.random()*4);
        switch(random_sign){
            case 0 : this.setRandom_sign("+");break;
            case 1 : this.setRandom_sign("-");break;
            case 2 : this.setRandom_sign("*");break;
            case 3 : this.setRandom_sign("÷");break;
        }
    }

RandomNum類:

public class RandomNum {//隨機生成一個數 a'b/c
    private int random_numerator;//a'b/c 的格式拆分成 a b c 隨機生成組合
    private int random_denominator;
    private int random_front;
    
    public String toStringSpit(){//進行區分 組成一個整體分數 
        if(this.getRandom_front()==0){
            if(this.getRandom_numerator() == this.getRandom_denominator()){
                return "1";
            }else return this.getRandom_numerator() + "/" + this.getRandom_denominator();//真分數
        }
        if(this.getRandom_denominator() == this.getRandom_numerator()){
            return Integer.toString(this.getRandom_front()+1);//整數
        }
        if(this.getRandom_numerator() == 0) return Integer.toString(this.getRandom_front());
        return this.getRandom_front() + "'" + this.getRandom_numerator() + "/" + this.getRandom_denominator();//假分數
    }
    
    public void SplitANum(String str){//把9‘1/5反向 拆分成類(此處預設所有數為如此格式)
        String[] parts;
        int temp;
        parts = str.split("'");
        temp = Integer.parseInt(parts[0]);
        this.random_front = temp;
        parts = parts[1].split("/");
        temp = Integer.parseInt(parts[0]);
        this.random_numerator = temp;
        temp = Integer.parseInt(parts[1]);
        this.random_denominator = temp;
    }
    
    public String toString(){//預設
        return this.getRandom_front() + "'" + this.getRandom_numerator() + "/" + this.getRandom_denominator();//都返回假分數
    }

RandomQuestion類:
生成括弧參考(就不貼出來了):參考

public RandomQuestion(int qnum_range){//生成題目 用ArrayList存取
        int sign_num = (int)(Math.random()*4+1);//骰子判斷生成題目長度
        //this.randomquestion = null;
        int flag = 0;
        RQ(qnum_range,sign_num,flag);//遞歸實現題目生成 具體就不貼了
    }

2. 答案計算:

中綴轉換尾碼 對尾碼表達式進行求答案。

轉尾碼遵循規則:參考

  • 遇到操作數,直接輸出;
  • 棧為空時,遇到運算符,入棧;
  • 遇到左括弧,將其入棧;
  • 遇到右括弧,執行出棧操作,並將出棧的元素輸出,直到彈出棧的是左括弧,左括弧不輸出;
  • 遇到其他運算符’+”-”*”/’時,彈出所有優先順序大於或等於該運算符的棧頂元素,然後將該運算符入棧;
  • 最終將棧中的元素依次出棧,輸出。

ChangeToRPN類:

public class ChangeToRPN {//a+b*c+(d*c+f)g -> abc*+de*f+g*+  中綴轉尾碼
    public ArrayList<Object> changetoRPN(ArrayList<Object> rq){
        ArrayList<Object> rpn = new ArrayList<Object>();
        Stack sk = new Stack();
        String temp_stackpop;
        for(int i = 0; i <= rq.size()-2; i++){
            if(IsSign(rq.get(i).toString())){//判斷是不是符號
                if(sk.getTop() == -1 || rq.get(i).toString() == "("){//棧空 和(  直接入棧
                    sk.push(rq.get(i).toString());
                }else{
                    if(rq.get(i).toString() == ")"){
                        while(sk.getTop() != -1 && sk.top().toString() != "("){
                            temp_stackpop = sk.pop().toString();
                            if(temp_stackpop != "(") rpn.add(temp_stackpop);
                        }
                    }else{//遇到別的操作符 判斷優先順序
                        while(sk.getTop() != -1 && GetPriority(sk.top().toString(),true) 
                                      >= GetPriority(rq.get(i).toString(),false)){
                            temp_stackpop = sk.pop().toString();
                            if(temp_stackpop != "(") rpn.add(temp_stackpop);
                        }
                        sk.push(rq.get(i));
                    }
                }
            }else rpn.add(rq.get(i));
        }
        while(sk.getTop()!=-1){
            temp_stackpop = sk.pop().toString();
            if(temp_stackpop != "(") rpn.add(temp_stackpop);
        }
        return rpn;
    }
    
    //flag true->棧內  符號優先順序
    int GetPriority(String operator, boolean flag)
    {
        if (operator == "+" || operator == "-")
        {
            if (flag) return 3;
            else return 2;
        }
        else if (operator == "*" || operator == "÷")
        {
            if (flag) return 5;
            else return 4;
        }
        else if (operator == "(")
        {
            if (flag) return 1;
            else return 6;
        }
        else if (operator == ")")
        {
            if (flag) return 6;
            else return 1;
        }
        return 0;
    }
}

不得不講一下,逆波蘭式在挺早的時候就學過了,然而還是完全忘了。。最終還是複習了下,才想起來整體流程。

Answer類:

public String GetAnswer(ArrayList<Object> rpn){
         Stack sk = new Stack();
         String rpn_temp;
         String num1,num2;
         String sk_temp;
         for(int i = 0; i <= rpn.size()-1; i++){
             rpn_temp = rpn.get(i).toString();
             if(IsSign(rpn_temp)){
                 num2 = sk.pop().toString();//註意出棧順序 這邊應該是 num2 後 num1
                 num1 = sk.pop().toString();
                 sk_temp = TwoNumCount(num1,num2,rpn_temp);//對兩個數求值
                 if(sk_temp != "-1") sk.push(sk_temp);
                 else return "-1";//返回-1表示該式子求值失敗 調用處continue
             }else sk.push(rpn_temp);
         }

         String result = sk.pop().toString();
         RandomNum rq = new RandomNum();
         rq.SplitANum(result);
         return rq.toStringSpit();
      }
    }

3. 題目查重:

Tree類:
5+6-2 —>56+2- 的轉化存儲過程:

public class Tree {
    private double result;//存取當前節點計算的值
    private String value;//存取當前節點值
    private Tree lchild;
    private Tree rchild;
    
    //生成樹中的規則
    public boolean Compare(Tree tree1, Tree tree2){//true——>tree1 左邊
        ChangeToRPN rpn = new ChangeToRPN();
        int flag = 0;
        if(tree1.getResult() > tree2.getResult()) flag = 1;
        else if(tree1.getResult() < tree2.getResult()) flag = 2;
        else flag = 3;
        
        if(flag == 1) return true; //值大的為左
        else if(flag == 2) return false;
        else if(tree1.getLchild() == null && tree2.getLchild() == null) return true;//2 2相等但是沒有孩子
        else if(rpn.GetPriority(tree1.getValue().toString(), true) // 值相等 運算符大的 左
                > rpn.GetPriority(tree2.getValue().toString(), true)) return true;
        else if(rpn.GetPriority(tree1.getValue().toString(), true) // 值和運算符都等  則子樹的左子樹值大的  左
                == rpn.GetPriority(tree2.getValue().toString(), true)){
            
            if(tree1.getLchild().getResult() > tree2.getLchild().getResult()) flag = 1;
            else if(tree1.getLchild().getResult() < tree2.getLchild().getResult()) flag = 2;
            else flag = 3;
            
            if(flag == 1) return true; 
            else if(flag == 2) return false;
            else return true;
        }
        return false;//tree2應為左
    } 
}

4. 運行測試


5. PSP

PSP2.1 Personal Software Process Stages Time Senior Student Time
Planning 計劃 10 10
· Estimate 估計這個任務需要多少時間 10 10
Development 開發 600 900
· Analysis 需求分析 (包括學習新技術) 30 30
· Design Spec 生成設計文檔 - -
· Design Review 設計覆審 - -
· Coding Standard 代碼規範 - -
· Design 具體設計 - -
· Coding 具體編碼 480 600
· Code Review 代碼覆審 240 120
· Test 測試(自我測試,修改代碼,提交修改) 200 120
Reporting 報告 240 180
· 測試報告 50 50
· 計算工作量 10 10
· 並提出過程改進計劃 - -

6. 總結

做這個項目還是花了很多時間的,大多是下課後過去圖書館然後做這個了。做的時候碰到挺多問題的吧,最大的是一開始沒有構思好具體思路,到了做著的時候發現行不通,後來還是再構想後,決定重新開始做。

具體編碼這部分雖然一開始就覺得會花很久,結果真正做的時候發現,出現bug是真的耗費時間。

這個表格的時間我其實我並沒有很詳細的算了,因為做的時候零零散散的,所以時間也沒有很好的統計,只是大概估計了下。

測試這一塊我覺得我做的不夠好,可以考慮用下單元測試,就像寫二叉樹查重那塊,我是整體寫完了,才開始測試,所以出現了有的讀空,也有其他的細節小問題,比如出棧數的操作對於減法除法應該反著來的,起初沒考慮到,後面發現才改過來。

後來在進一步優化代碼以及寫寫註釋什麼的,也花了一些時間。

表裡面的有的還不太清楚,所以就沒寫了。

第一次寫博客!偷偷標記!



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 破解intelij IDEA請見鏈接:https://blog.csdn.net/weixin_37937646/article/details/79119540 ...
  • 1.編譯 go build hello.go 2.go get gopl.io/ch1/helloworld 命令,就會從網上獲取代碼,並放到對應目錄中 下載的代碼會放在$GOPATH/src/gopl.io/ch1/helloworld目錄 3.Go語言不需要在語句或者聲明的末尾添加分號,除非一行 ...
  • 1、指定序列化順序 預設fastjson序列化一個java bean,是根據fieldName的字母序進行序列化的,你可以通過ordinal指定欄位的順序。這個特性需要1.1.42以上版本。 1 public static class VO { 2 @JSONField(ordinal = 3) 3 ...
  • Idea 作為一個每天有一半時間都在電腦旁的人,無時無刻不在敲擊著鍵盤,點擊著滑鼠。有一天,我突然很想知道在一天的時間內,在我輕盈的指法下麵,鍵盤被我狂敲了多少下,滑鼠又被我點擊了多少次。甚至更具體一些,鍵盤上哪些鍵挨的敲擊次數更多呢?想想也覺得挺有意思的。 <! more Learing 有了想法 ...
  • 1,大小寫翻轉 2,從一串字元串中,提取純數字組合 等價於: 3,統計字元的出現次數,以字元為鍵,大小寫視為相同字元 4,字元串去重,按原來的順序輸出 5,字元串反轉 6,去除字元串中的數字,然後排序,如果出現相同的字母,如aA,大寫字母排在小寫字母的前面 ...
  • Problem Description 在每年的校賽里,所有進入決賽的同學都會獲得一件很漂亮的t-shirt。但是每當我們的工作人員把上百件的衣服從商店運回到賽場的時候,卻是非常累的!所以現在他們想要尋找最短的從商店到賽場的路線,你可以幫助他們嗎? Input 輸入包括多組數據。每組數據第一行是兩個 ...
  • 1,二進位方式 2,移位運算符( >> << ): 箭頭向左就是 向左移位 反正 箭頭向右 就是向右位移,移位針對的是二進位 如,十進位的1 > 對應的二進位是 0000 0001 1 << 1 : 向左移動1位 0000 0001 >0000 0010( 2 ) 1 << 2 : 向左移動2位 0 ...
  • 今天書接昨天的函數繼續去學習瞭解: 昨天說到函數的動態參數。 1、函數的【動態參數】 2、函數中【\ 和 的魔法運用】 在函數的調用(執行)時, 加一個可迭代對象(列表,元祖,字元串,字典等)代表解包, (列表元祖打散成列表中的每個元素,字元串打散成每個字元,字典打散成每個鍵) 並將元素一 一添加進 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...