2017-2018-2 1723 『Java程序設計』課程 結對編程練習-四則運算-準備階段

2017-2018-2 1723 『Java程序設計』課程

結對編程練習-四則運算-準備階段

在一我的孤身奮鬥了將近半個學期之後,終於迎來的咱們的第一次團隊協做共同編碼,也就是,咱們的第一個結對編程練習——四則運算。顯然,他是考驗咱們對於以前知識的掌握程度,並且考驗咱們的能力,既然已是一個結對編程練習,確定存在着困難,但咱們會迎難而上,一塊兒解決問題,由於「團結就是力量!!!」html

結對編程的戰友

20172316 趙乾宸:負責對於整數出題的編程;
20172319 唐才銘:負責對於分數出題的編程;
我:20172329 王文彬:負責對於計算和題目去重的編寫;
測試爲分別進行測試,最後由趙乾宸進行集體測試。
每一個人都是駕駛員,是彼此的引航員,團隊,分工明確是一部分,可是集體力量的結晶纔是最偉大的!!!java

看到題目的構思

一、計算的最開始構思:
首先,當第一次拿到這個題目的時候,首先進行思考的是加減乘除的整個運算邏輯,由於當時沒有了解過有後綴表示法,因此一直在想如何用中綴表達式開始計算; 一方面,思考的是輸出的題目應該是字符串類型仍是數據類型,後來想了想,各有各自的優勢和缺點,好比,計算的時候的確,數字是很方便的,可是當涉及到計算的時候,遇到的「+」、「-」、「*」、「/」,幾個符號就我如今的水平,沒有辦法去很好的解決,以後就想到了,假如將這幾個運算符號進行改變,將其變爲幾個數字表明他們,不就能夠了,最後有這樣一個問題,若是用「0」來表明「+」,有一個問題,由於「+」是一個字符串,對其賦值還得進行強制轉化,對於程自己這樣實際上是不利的,存在着必定的問題,因此,就先將計算問題放了放,開始想,如何出題;編程

二、開始出題:
最開始,仍是以出題爲主,考慮到「if-else」語句的複雜性,咱們選擇了「swich語句「,由於,這樣能夠進行人機互動,一方面能夠實現咱們所須要的輸入一個階數,能夠完成對於該階數的出題;構思是這樣的,先利用對於符號的賦值,對於加減乘除四個符號進行對0123的賦值,以便於經過對於產生一個0~4(左閉右開)的一個隨機數取值實現對於字符串的出題的隨機性,將輸出的符號給一個字符對象進行賦值,以後,開始在裏面加入數字,如何解決階數的控制,一方面,利用swich語句的方便,其次,利用了累加「+=」進行輸出,就會產生按照咱們需求的題目;另外一方面,須要輸出按照咱們所敲入的數字進行題目個數的輸出,咱們想到了運用數組和while語句,這樣,按照條件,輸出數組,就能夠達到咱們想要的一個結果,也就是一個理想的出題模型。數組

protected int a;
    protected String s1 = "", str = "";

    public Compute2() {
        Scanner scan = new Scanner(System.in);
        System.out.println("幾級運算?");
        int n = scan.nextInt();
        Scanner qqq = new Scanner(System.in);
        System.out.println("生成幾個題目?");
        int q = qqq.nextInt();
        Object[] p = new Object[q] ;
        for (int index = 0; index < q; index++) {
            int a1 = (int) (Math.random() * 100);
            int a2 = (int) (Math.random() * 100);
            int t1 = (int) (Math.random() * 4);
            switch (t1) {
                case 0: {
                    s1 = " + ";
                    break;
                }
                case 1: {
                    s1 = " - ";
                    break;
                }
                case 2: {
                    s1 = " * ";
                    break;
                }
                case 3: {
                    s1 = " / ";
                }
            }
            for (int i = 0; i < n - 1; i++) {
                int a = (int) (Math.random() * 100);
                int t = (int) (Math.random() * 4);
                String s = "";
                switch (t) {
                    case 0: {
                        s = " + ";
                        break;
                    }
                    case 1: {
                        s = " - ";
                        break;
                    }
                    case 2: {
                        s = " * ";
                        break;
                    }
                    case 3: {
                        s = " / ";
                    }
                }
                str += a + s;

            }

            str += a1 + s1 + a2;
            p[index]=str;

三、學習從中綴表達式到後綴表達式的變化:
在課上,學習瞭解了後綴表達式,這個表達式方便了咱們進行計算代碼的編寫,利用了「棧」這個概念,在思考運算的過程當中簡化了不少步驟;
在利用棧解決問題的時候有一個問題:就是假如是兩位數,如何去解決,這個問題在某一天的晚自習裏,學長給咱們就這個問題進行了講解,利用StringTokenzer的方法進行對於字符串的分隔,這個方法能夠將兩個數字或者三個乃至三個以上的字符進行劃分,讓他們單獨成爲總體,這樣就方便了咱們的計算,就能夠解決1234+不是123+4而是12+34的問題,感謝學長。dom

public String infixToSuffix() {
                Stack<Character> s = new Stack<Character>();
               String suffix = "";
        int length = str.length();         for (int i = 0; i < length; i++) {
            char temp;// 臨時字符變量
                        char ch = str.charAt(i);
            switch (ch) {
                               case ' ':
                    break;
                               case '(':
                    s.push(ch);
                    break;
                               case '+':
                case '-':
                    while (s.size() != 0) {
                        temp = s.pop();
                        if (temp == '(') {
                                                       s.push('(');
                            break;
                        }
                        suffix += temp;
                    }
                                       s.push(ch);
                    break;
                                case '*':
                case '/':
                    while (s.size() != 0) {
                        temp = s.pop();
                                                if (temp == '+' || temp == '-' || temp == '(') {
                            s.push(temp);
                            break;
                        } else {
                            suffix += temp;
                        }
                    }
                                       s.push(ch);
                    break;
                               case ')':
                                       while (!s.isEmpty()) {
                        temp = s.pop();
                        if (temp == '(') {
                            break;
                        } else {
                            suffix += temp;
                        }
                    }
                    break;
                               default:
                    suffix += ch;
                    break;
            }
        }
               while (s.size() != 0) {
            suffix += s.pop();
        }        return suffix;

四、在出題過程當中去重問題上的思考:
如何去重,一方面,咱們想到的是隻要是結果相同的就是相同的,後來,發現並非這樣簡單的,由於,在看了老師的博客中所介紹的:學習

程序一次運行生成的題目不能重複,即任何兩道題目不能經過有限次交換+和×左右的算術表達式變換爲同一道題目。例如,23 + 45 = 和45 + 23 = 是重複的題目,6 × 8 = 和8 × 6 = 也是重複的題目。3+(2+1)和1+2+3這兩個題目是重複的,因爲+是左結合的,1+2+3等價於(1+2)+3,也就是3+(1+2),也就是3+(2+1)。可是1+2+3和3+2+1是不重複的兩道題,由於1+2+3等價於(1+2)+3,而3+2+1等價於(3+2)+1,它們之間不能經過有限次交換變成同一個題目。測試

看到了如此的要求,就開始進行思考;編碼

五、計算問題:(我是負責這裏部分編寫的)
在碰見計算的時候,主要靠的就運用後綴表達式的方法,利用棧進行計算,大概思路以下:spa

public Integer suffixToArithmetic() {
               Pattern pattern = Pattern.compile("\\d+||(\\d+\\.\\d+)");
               String[] strings = str.split("");
        Stack<Integer> stack = new Stack<Integer>();
        for (int i = 0; i < strings.length; i++) {
                       if (strings[i].equals("")) {
                continue;
            }
                        if (pattern.matcher(strings[i]).matches()) {
                stack.push((int) Double.parseDouble(strings[i]));
            }
                       else {
                             double y = stack.pop();
                double x = stack.pop();
                               stack.push((int) calculate(x, y, strings[i]));
            }
        }
             return stack.pop();
    }
    private  double calculate(double x, double y, String string) {

               if (string.trim().equals("+")) {
            return x + y;
        }
        if (string.trim().equals("-")) {
            return x - y;
        }
        if (string.trim().equals("*")) {
            return x * y;
        }
        if (string.trim().equals("/")) {
            return x / y;
        }
        return (double) 0;
    }

測試結果

轉後綴:
.net

遇到的一些問題

第一個問題:
如何去解決出題過程當中如何去添加括號,由於括號的位置的不肯定性就限制了咱們如何去選擇,好比,假如出現像加法和乘法混在一塊兒,括號應該選擇加在加法位置?
解決方案:
咱們想要將加法和括號綁定在一塊兒,以後利用swich語句判斷,何時不須要在加法減法周圍加括號,何時不須要加。

第二個問題:
由於咱們是先進行了代碼的編寫,而後經過對於代碼畫UML圖,因此如今就有以一個問題,由於一些代碼命名不一樣,使得存在一些問題,(這個是咱們組的失誤,下次會糾正的)
解決方案:
如今正在彙總,以後打算統一爲UML圖的編碼格式,而後對各自的代碼進行修改。

互評

20172316趙乾宸
小趙同窗擔起了開始編寫代碼的大任,在發佈任務的次日,由於我和老唐同窗在連續的兩天都有晚課,因此一開始,小趙同窗的功勞功不可沒,並且他是咱們團隊編程能力最強的,因此,咱們都會向他看齊。
20172319唐才銘
老唐同窗分配了咱們的任務,而且也擔起了團隊的一遍大旗,爲彼此加油鼓勁。
你們加油!!

UML圖

PSP

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 60 60
Estimate 估計這個任務須要多少時間 100 100
Development 開發 800
Analysis 需求分析 (包括學習新技術) 100 60
Coding Standard 代碼規範 (爲目前的開發制定合適的規範) 30 20
Design UML 設計項目UML類圖 50 30
Coding 具體編碼 30
Code Review 代碼複審 50
Test 測試(自我測試,修改代碼,提交修改) 30
Size Measurement 計算工做量(實際時間 30
Postmortem & Process Improvement Plan 過後總結, 並提出過程改進計劃 30
合計 1240

參考

Java堆棧的應用2----------中綴表達式轉爲後綴表達式的計算Java實現
用java實現複數的加減乘除運算
逆波蘭表達式
表達式計算 java 後綴表達式
Java實現中綴表達式轉後綴表達式並計算結果

相關文章
相關標籤/搜索