軟體工程(2018)結對編程第二次作業

来源:https://www.cnblogs.com/-yanghao/archive/2019/05/05/10810083.html
-Advertisement-
Play Games

[toc] 一.題目要求 我們在剛開始上課的時候介紹過一個小學四則運算自動生成程式的例子,請實現它,要求: 能夠自動生成四則運算練習題 可以定製題目數量 用戶可以選擇運算符 用戶設置最大數(如十以內、百以內等) 用戶選擇是否有括弧、是否有小數 用戶選擇輸出方式(如輸出到文件、印表機等) 最好能提供圖 ...


目錄

一.題目要求

  • 我們在剛開始上課的時候介紹過一個小學四則運算自動生成程式的例子,請實現它,要求:
    • 能夠自動生成四則運算練習題
    • 可以定製題目數量
    • 用戶可以選擇運算符
    • 用戶設置最大數(如十以內、百以內等)
    • 用戶選擇是否有括弧、是否有小數
    • 用戶選擇輸出方式(如輸出到文件、印表機等)
    • 最好能提供圖形用戶界面(根據自己能力選做,以完成上述功能為主)

二.角色分工

駕駛員:楊浩(本人)
領航員:馮俊鵬 博客地址

三.代碼及代碼地址

代碼地址

題目生成

class BinaryTree 
{
    
    private TreeNode root;
    private int num;
    private ArrayList<TreeNode> opeList = new ArrayList<TreeNode>();
    
    public BinaryTree(int num){
        this.num=num;
    }
    
    public int getNum(){
        return num;
    }
    
    public void setNum(int num){
        this.num = num;
    }
    
    public void setTreeNode(TreeNode root){
        this.root = root;
    }
    
    
    /**
     * 獲取最終的表達式,必須在CalAndVal()方法後調用
     * 
     * @return str
     */
    public String toString(){
        String str = root.toString();
        str = str.substring(1, str.length()-1);
        return str;
    }
    
    /**
     * 計算並驗證表達式
     * 
     * @return result
     */
    public String CalAndVal(){
        return root.getResult();
    }
    
    /**
     * 計算二叉樹的深度(層數) 
     * 
     * @return deep
     */
    public int getDeep(){
        int i = this.num;
        int deep = 2;
        while(i/2 > 0){
            deep++;
            i /= 2;
        }
        return deep;
    }
    
    /**
     * 生成二叉樹
     * 
     */
    public void createBTree(){
        TreeNode lchild, rchild, lnode, rnode;
        
        if(num == 1){
            lchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);
            rchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);
            root = new TreeNode(String.valueOf(Ran.getOperator()), lchild, rchild);
        }
        else{
            int num1 = 0;
            int n = getDeep() - 3;
            boolean[] place = Ran.getChildPlace(num);
            root = new TreeNode(String.valueOf(Ran.getOperator()), null, null);
            opeList.add(root);
            
            for(int i = 0; i < n; i++){
                for(int j = 0; j < (int)Math.pow(2, i); j++, num1++){
                    lchild = new TreeNode(String.valueOf(Ran.getOperator()), null, null);
                    rchild = new TreeNode(String.valueOf(Ran.getOperator()), null, null);
                    opeList.get(j + num1).setChild(lchild, rchild);  //?
                    opeList.add(lchild);
                    opeList.add(rchild);
                }
            }
            
            for(int i = 0; i < place.length; i++){
                if(place[i]){
                    lnode  = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);
                    rnode  = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);
                    if(i%2 == 0){
                        lchild = new TreeNode(String.valueOf(Ran.getOperator()), lnode, rnode);
                        opeList.add(lchild);
                        opeList.get(num1).setLchild(lchild);
                    }
                    else{
                        rchild = new TreeNode(String.valueOf(Ran.getOperator()), lnode, rnode);
                        opeList.add(rchild);
                        opeList.get(num1).setRchild(rchild);
                    }
                }
                else{
                    if(i%2 == 0){
                        lchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);
                        opeList.get(num1).setLchild(lchild);
                    }
                    else{
                        
                        rchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);
                        opeList.get(num1).setRchild(rchild);
                    }
                }
                num1 = num1 + i%2;
            }
        }
    }
}

 class Ran {
    
    /**
     * 獲取隨機的符號
     * 
     * @return operator
     */
    
    public static char getOperator(){
        char operator = 0;
        Random ran = new Random();
        int i = ran.nextInt(4);
        switch(i){
            case 0:
                operator = '+';
                break;
            case 1:
                operator = '-';
                break;
            case 2:
                operator = '*';
                break;
            case 3:
                operator = '/';
                break;
        }
        return operator;
    }
    
    
    /**
     * 根據輸入的範圍獲取隨機數
     * 
     * @param max
     * @return number
     */
    
    public static int getNumber(int max){
        int number = 0;
        max=test.maxNum;
        
            Random ran = new Random();
            number = ran.nextInt(max+1);
            return number;
    }
    
    /**
     * 根據運算符的個數隨機產生子節點的位置
     * 
     * @param num
     * @return childPlace
     */
    
    public static boolean[] getChildPlace(int num){
        int d = 0;
        int size = 0, j=1;
        while(num >= (int)Math.pow(2, j)){
            j++;
        }
        d = (int)Math.pow(2, j) - 1 - num;
        size = (int)Math.pow(2, j-1);
        boolean[] k = new boolean[size];
        for(int i = 0; i < size; i++){
            k[i] = true;
        }
        for(int i = 0; i < d; i++){
            Random ran = new Random();
            int f = ran.nextInt(size);
            while(k[f] == false)
            {
                f = ran.nextInt(size);
            }
            k[f] = false;
        }
        return k;
    }
}

 class TreeNode {
    
    private String str;
    private TreeNode rchild = null;
    private TreeNode lchild = null;
    
    public TreeNode(String str){
        this.str = str;
    }
    
    public TreeNode(String str, TreeNode lchild, TreeNode rchild){
        this.str = str;
        this.rchild = rchild;
        this.lchild = lchild;
    }
    
    public void setChild(TreeNode lchild, TreeNode rchild){
        this.lchild = lchild;
        this.rchild = rchild;
    }
    
    public TreeNode getRchild() {  
        return rchild;  
    }  
    public void setRchild(TreeNode rchild) {  
        this.rchild = rchild;  
    }  
    public TreeNode getLchild() {  
        return lchild;  
    }  
    public void setLchild(TreeNode lchild) {  
        this.lchild = lchild;  
    }
    
    public String getStr(){
        return str;
    }
    
    /**
     * 獲取每個節點的運算結果,並檢驗除法
     * 1)除數為0
     * 2)不能整除
     * 出現以上兩種情況的話將該運算符轉換成其他三種運算符
     * 
     * @return result
     */
    public String getResult(){
        if(hasChild()){
            switch(str){
                case "+":
                    return String.valueOf(Integer.parseInt(getLchild().getResult()) + Integer.parseInt(getRchild().getResult()));
                case "-":
                    return String.valueOf(Integer.parseInt(getLchild().getResult()) - Integer.parseInt(getRchild().getResult()));
                case "*":
                    return String.valueOf(Integer.parseInt(getLchild().getResult()) * Integer.parseInt(getRchild().getResult()));
                case "/":
                    if(getRchild().getResult().equals("0")){
                        while(str.equals("/")){
                            str = String.valueOf(Ran.getOperator());
                        }
                        return this.getResult();
                    }
                    else if(Integer.parseInt(getLchild().getResult()) % Integer.parseInt(getRchild().getResult()) != 0){
                        while(str.equals("/")){
                            str = String.valueOf(Ran.getOperator());
                        }
                        return this.getResult();
                    }
                    else
                        return String.valueOf(Integer.parseInt(getLchild().getResult()) / Integer.parseInt(getRchild().getResult()));
            }
        }
        return str;
    }     
    
    /**
     * 先對每個運算式添加括弧,然後根據去括弧法則,去掉多餘的子式的括弧
     * 
     * @return string
     */
    public String toString(){
        String Lstr = "", Rstr = "", Str = "";
        if(hasChild()){
            //右子樹如果有孩子,說明右子樹是一個表達式,而不是數位元組點。
            if(getRchild().hasChild()){                         
                //判斷左鄰括弧的運算符是否為'/'
                if(str.equals("/")){
                    //獲取右子樹的表達式,保留括弧
                    Rstr = getRchild().toString();              
                }
                //判斷左鄰括弧的運算符是否為'*'或'-'
                else if(str.equals("*") || str.equals("-")){
                    //判斷op是否為'+'或'-'
                    if(getRchild().str.equals("+") || getRchild().str.equals("-")){ 
                        Rstr = getRchild().toString();          
                    }
                    else{
                        //獲取右子樹的表達式,並且去括弧 
                        Rstr = getRchild().toString().substring(1, getRchild().toString().length()-1);  
                    }
                }
                else{
                    //右子樹除此之外都是可以去括弧的。
                    Rstr = getRchild().toString().substring(1, getRchild().toString().length()-1);      
                }
            }
            else{
                Rstr = getRchild().str;
            }
            //左子樹的情況同右子樹類似
            if(getLchild().hasChild()){                                             
                if(str.equals("*") || str.equals("/")){
                    if(getLchild().str.equals("+") || getLchild().str.equals("-")){
                        Lstr = getLchild().toString();
                    }
                    else{
                        Lstr = getLchild().toString().substring(1, getLchild().toString().length()-1);
                    }
                }
                else{
                    Lstr = getLchild().toString().substring(1, getLchild().toString().length()-1);
                }
            }
            else{
                Lstr = getLchild().str;
            }
            //獲取當前的運算式,並加上括弧
            Str = "(" + Lstr + str + Rstr + ")";                                    
        }
        else{
            //若沒有孩子,說明是數位元組點,直接返回數字
            Str = str;
        }
        return Str;
    }
    
    public boolean hasChild(){
        if(lchild == null && rchild == null)
            return false;
        else
            return true;
    }
}

圖形界面生成及輸出

public static void InitUI()
    {
        JFrame frame =new JFrame();
        frame.setTitle("四則運算");
        frame.setSize(500, 500);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(3);
        
        FlowLayout f1=new FlowLayout(FlowLayout.LEFT);
        frame.setLayout(f1);
        
        JLabel name1=new JLabel("請輸入題目個數:");
        frame.add(name1);
        
        JTextField name1text=new JTextField();//文本框
        name1text.setPreferredSize(new Dimension(50, 30));
        frame.add(name1text);
        
        JLabel name=new JLabel();//空
        name.setPreferredSize(new Dimension(110,30));
        frame.add(name);
        
        JLabel name2=new JLabel("請輸入最大值:");
        frame.add(name2);
        
        JTextField name2text=new JTextField();//文本框
        name2text.setPreferredSize(new Dimension(50, 30));
        frame.add(name2text);
        
        JLabel name4=new JLabel("是否輸出到文件:");
        frame.add(name4);
        
        JRadioButton jrb1, jrb2;
        jrb1 = new JRadioButton("是");
        jrb2 = new JRadioButton("否");
        frame.add(jrb1);
        frame.add(jrb2);
        
        JLabel name5=new JLabel();//空
        name5.setPreferredSize(new Dimension(110,30));
        frame.add(name5);
        
        JButton bu=new JButton("生成");
        bu.setPreferredSize(new Dimension(80,30));
        frame.add(bu);
        
        JLabel name3=new JLabel();//空
        name3.setPreferredSize(new Dimension(50,30));
        frame.add(name3);
        
        JLabel name7=new JLabel("題目:");
        frame.add(name7);
        
        JLabel name6=new JLabel();//空
        name6.setPreferredSize(new Dimension(250,30));
        frame.add(name6);
        
        JTextField Titletext=new JTextField();//文本框
        Titletext.setPreferredSize(new Dimension(450, 300));
        frame.add(Titletext);
        
        
        /**
         * 事件監聽器
         */
        bu.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                String a=name1text.getText();
                int Title_Num = Integer.parseInt(a);  //string轉換為int
                String b=name2text.getText();
                maxNum = Integer.parseInt(b);  //string轉換為int
                String[] Title=new String[Title_Num];
                String[] result1=new String[Title_Num];
                for(int i = 0; i < Title_Num; i++){
                    BinaryTree bTree;
                    bTree = new BinaryTree(2);
                    bTree.createBTree();
                    String result = bTree.CalAndVal();
                    Title[i]=bTree.toString();
                    result1[i]=result;
                    System.out.println(Title[i]+"="+result1[i]);
                }
                
                
                    Titletext.setText(getStringByArray(Title,result1));
                
                /**
                 * 文件輸出
                 */
                if(jrb1.isSelected()) {
                    try{
                        PrintStream mytxt=new PrintStream("./test.txt");
                        PrintStream out=System.out;
                        System.setOut(mytxt);
                        for(int i = 0; i < Title_Num; i++){
                            System.out.println(Title[i] + "=" + result1[i]);
                        }
                        System.setOut(out);
                        }catch(FileNotFoundException e1){
                        e1.printStackTrace();
                        }
                }
                
            }
        });
        
        frame.setVisible(true);
    }
    /**
     * 
     * @將題目整和成一個字元串,方便setText輸出
     * @param b
     * @return str
     */
    public static String getStringByArray(String[] a,String[] b) {
        String str = "";
        for(int i=0;i<a.length;i++) {
            str += a[i];
            str += '=';
            str += b[i];
            str += ' ';
            str += ' ';
            str += ' ';
            str += ' ';
        }
        return str;
    }

四.運行結果截圖

圖形框架截圖

輸出到文本框

輸出到文件

五.參考資料

隨機生成四則運算式及答案(含括弧)
如何將java的輸出保存到文件中作為程式日誌
Java實現圖形界面
Java 圖形化界面設計(GUI)實戰練習(代碼)
Java如何畫圖形用戶界面
java按鈕的監聽事件
java圖形界面中怎麼用settext輸出一個數組

六.工作照片

七.評價及總結

 在這次的作業中,我的領航員是馮俊鵬同學,他在過程中給了我很大的幫助,不斷地督促我儘快完成,遇到不會的問題和我一起解決,是使我的代碼更加完善,沒有他的話我很難完成這次的作業。
 通過這次作業,我完成了我的第一個擁有圖形界面的作品,在這之前一直都是用黑框進行操作,編寫代碼的過程是非常困難的,有許許多多的問題根本不知道如何解決,例如圖形化界面的實現、界面的輸入和輸出和事件監聽器的編寫等等,碰到這些問題只能去網上搜索 ,找了很多的參考文章,上面列舉出的僅僅只是其中一小部分,程式實現了一部分功能,但還有幾個功能沒有實現,例如選擇小數和選擇括弧,圖形界面的編寫也比較混亂,但是,在這次的代碼編寫過程中,我學到了很多以前根本不會的知識,收穫了很多。


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

-Advertisement-
Play Games
更多相關文章
  • jquery的浪漫 主要用到知識點: 滑鼠事件onmousedown() onmousemove() onmouseup() jquery的運用,對dom元素的增刪改查 css3 3d 功能的靈活運用 實現的功能 跑馬燈效果 文字自動輸入 雪花飄落 滑鼠點擊 滑動生成雪花 背景音樂等 看效果 htm ...
  • 好幾天沒有更新了,直接上效果吧,哈哈!(我想這個應該大部分都會!哈哈哈!) 代碼如下: html: css: 大家一起努力吧!! ...
  • ```js class TrieNode { constructor(data){ this.data = data this.children = new Array(26) this.isEndingChar = false this.text = '' } } class TrieTree {... ...
  • 如果第二次看到我的文章,歡迎右側掃碼訂閱我喲~ 👉 每周五早8點 按時送達。當然了,也會時不時加個餐~ Z哥在前面的三篇文章里和你一起聊了「高性能」主題下與「緩存」相關的內容。這次和你來聊聊提高性能的另一個大招——「非同步」。 如果你已經對「非同步」有所瞭解的話,這次可以讓你有更深刻的理解。如果你對「 ...
  • [TOC] 一. 簡述一致性哈希演算法 這裡不詳細介紹一致性哈希演算法的起源了, 網上能方便地搜到許多介紹一致性哈希演算法的好文章. 本文主要想動手實現一致性哈希演算法, 並搭建一個環境進行實戰測試. 在開始之前先整理一下 演算法的思路 : 一致性哈希演算法通過把每台伺服器的哈希值打在哈希環上, 把哈希環分成不 ...
  • const:靜態常量,也稱編譯時常量(compile-time constants),屬於類型級,通過類名直接訪問,被所有對象共用! a、叫編譯時常量的原因是它編譯時會將其替換為所對應的值; b、靜態常量在速度上會稍稍快一些,但是靈活性卻比動態常量差一些; c、靜態常量,隱式是靜態的,即被stati ...
  • 背景 電商中有這樣的一個場景: 1. 下單成功之後送積分的操作,我們使用mq來實現 2. 下單成功之後,投遞一條消息到mq,積分系統消費消息,給用戶增加積分 我們主要討論一下,下單及投遞消息到mq的操作,如何實現?每種方式優缺點? 方式一 step1:start transaction step2: ...
  • 老王的股票 大家好,我是小趙,目前任職藏劍山莊高級鑄劍師,在山莊裡和我玩的比較好的有老王和老劉他們幾個,都是組長級別的二貨們,經常混在一起打牌。 今天上午閑得蛋疼晃悠晃悠的晃到的老王的地盤,看到老王在埋頭寫程式: 這老王似乎在炒股票,好專業的樣子。 於是我伸手拍了拍老王的肩膀:“幹啥呢?”。 老王一 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...