2018-2019-2 《Java程序設計》結對項目階段總結《四則運算——整數》(二)

20175218 2018-2019-2 《Java程序設計》結對項目階段總結《四則運算——整數》

1、需求分析

實現一個命令行程序,要求:java

  • 自動生成小學四則運算題目(加,減,乘,除)
    • 文本支持整數
    • 支持多運算符(例如生成包含n個運算符的題目)
    • 支持真分數(後續實現)
  • 統計正確率

擴展需求git

  • 文件:
    • 處理生成題目並輸出到文件
    • 完成題目後從文件讀入並判斷
  • 多語言支持:簡體中文,繁體中文,English
  • 生成題目去重

2、設計思路以及代碼解釋

最開始看到這個結對項目的時候,我以爲,最爲第一個項目,應該不會很難。而在真正看到項目的時候,也感受不是很難。在這一點上,我和個人搭檔是同一個想法,都以爲還行。可是越是日後作,就愈加現,這怎麼這麼複雜...其實,是這樣的,最開始,咱們沒有考慮到括號、運算優先級以及多個數字運算的問題,就只是簡單設計了一個兩個數字簡單的四則運算,這個程序呢,我也發出來了,以下:編程

//生成隨機整數的運算數組

public class Zheng {
        int a=0,b=0,c=0;
    int result=0,g=0;
    String s=null;
    public void Zheng(){
        a = (int)(Math.random()*100);//生成0-99的隨機數
        b = (int)(Math.random()*100);
        c = (int)(Math.random()*4);//生成0-3的隨機數,用來隨機產生運算符
         if(c==0){
             System.out.println(a+"+"+b+"=");
             result = a + b;
         }
         if(c==1){
                         System.out.println(a+"-"+b+"=");
             result = a - b;
         }
                 if(c==2){
                         System.out.println(a+"*"+b+"=");
             result = a * b;
        }
                 if(c==3){
                      if(b==0){
                             while(b==0) 
                             b=(int)(Math.random()*10);//防止分母爲0
            }
                      else{ 
                         System.out.println(a+"/"+b+"=");
                         int smaller = a > b ? b : a;//將a與b中的最小值賦給變量
                         for (int i = 1; i <= smaller; i++) {
                 if (a % i == 0 && b % i == 0) {
                     g = i;
                 }//求a與b的最大公因子
             }
             a = a/g;
             b = b/g;
             s = a+"/"+b;
        }   
    }
  } 
}

//實現四則運算dom

import java.util.*;
public class YunSuan {
    public static void main (String args[]){
        int x,z=0;
        Zheng zheng = new Zheng();
        System.out.print("請輸入要生成的題目數:");
        Scanner reader = new Scanner(System.in);
        int n = reader.nextInt();
        Random random = new Random();
        for(int i=1;i<n+1;i++){
        for(;;){
            System.out.println("題目"+i+":");
            zheng.Zheng();
            System.out.print("請輸入結果:");
            if(zheng.c==3){
                Scanner sc=new Scanner(System.in);
                String s =new String();
                    s =sc.nextLine();
                if(s.equals(zheng.s)){
                    z++;
                    System.out.println("此題正確");
            }
                    else
                        System.out.println("此題錯誤,正確答案爲:"+zheng.s);
            }
            else{
            x =reader.nextInt();
            if(x==zheng.result){
                z++;
                    System.out.println("此題正確");
            }
            else
                System.out.println("此題錯誤,正確答案爲:"+zheng.result);
            
            }
                break;
              }
            }
        int o =(int)(((double)z/(double)n)*100);//計算正確率
            System.out.print("完成"+n+"道題,正確數目爲:"+z+",正確率爲:");
        System.out.printf("%d",o);
        System.out.println("%");
    }
}

四則運算簡版連接:碼雲連接命令行

然後來作的過程當中,發現不只僅是這麼簡單,咱們須要考慮到不少東西,包括括號、運算優先級以及多個數字計算的因素等。因而咱們卡在這裏好長時間,特別是在作棧以及中綴轉後綴這塊時,咱們不知道該如何作下去了。而後咱們就查資料以及加上咱們兩我的的共同思考,終於知道了如何解決括號與計算問題,經過一段時間的努力,最終得出了代碼。然而,依舊不是這麼簡單,咱們的代碼仍是有一些問題,代碼以下:設計

//生成隨機數code

import java.util.*;
public class RandomNum {
    int RandomNum(int x){
        int num =(int)(Math.random()*x);
        return num;
    }
}

//生成隨機運算符
import java.util.*;
public class RandomChar {
     char RandomChar(){
        int num = (int)(Math.random()*4);
        switch (num){
            case 0:return'+';
            case 1:return'-';
            case 2:return'*';
            case 3:return'÷';
            default:return 0;
        }
    }
}

//生成中綴表達式以及產生題目blog

import java.util.*;
public class Produce {
    void Produce(int n){
        RandomNum num = new RandomNum();
        RandomChar c = new RandomChar();
        Scanner reader = new Scanner(System.in);
        String s = "";
        String d = "";
        String g = "";
        String out = "";//最終的中綴表達式
        String end = "";//轉化後的後綴表達式
        int count = 0;//記錄作對的題目個數
            for(int i=1;i<n+1;i++){
            System.out.println("題目"+i+":");
            int a = (int)(Math.random()*5+1);
                int amount = num.RandomNum(a)+1;//記錄隨機產生運算符的個數
            for(int j=0;j<amount;j++){
            s = s+c.RandomChar()+" ";
            }
            String str[] = s.split(" ");//將字符串轉化成字符串數組
            for(int z=0;z<str.length;z++){
                d = d+num.RandomNum(50)+str[z];
            }
            d = d + num.RandomNum(50);
            switch((num.RandomNum(2))){
                case 0:
                    System.out.println(d+" = ");//輸出不帶括號的中綴表達式
                    break;
                case 1:
                        for(int k=0;k<str.length;k++){
                           g = num.RandomNum(50)+ str[num.RandomNum(str.length-1)] + "(" + num.RandomNum(50) + str[num.RandomNum(str.length-1)] + num.RandomNum(50) + ")" + str[k];
                    }//在中綴表達式中加入括號
                    g = g + num.RandomNum(50);
                    System.out.println(g+" = ");//輸出不帶括號的中綴表達式
                                        break;

            }
            out = g;
            out = d;
            int p = 0;//初始化最終獲得的答案
            infixToSuffix in = new infixToSuffix();
            end = in.infixToSuffix(out);//將中綴表達式轉化爲後綴表達式
            suffixToArithmetic ex = new suffixToArithmetic();
            p = (int) ex.suffixToArithmetic(end);//計算後綴表達式的結果
                System.out.print("請輸入結果:");
            int x = reader.nextInt();
            if(x==p){
                System.out.println("結果正確!");
                count++;
            }
            else{
                System.out.println("結果錯誤,正確結果是:"+p);
            }
            s="";
            g="";
            d="";
        }
        int result = (int)(((double)count/(double)n)*100);//計算正確率
        System.out.println("總共答題"+n+"道,正確率爲:"+result+"%");
    }
    
}

//將中綴表達式轉化爲後綴表達式隊列

import java.util.*;
public class infixToSuffix {
public static String infixToSuffix(String infix) {
        Stack<Character> stack = new Stack<Character>();
        String suffix = "";
        int length = infix.length();
        for (int i = 0; i < length; i++) {
            Character temp;
            char c = infix.charAt(i);
            switch (c) {
                // 忽略空格
                case ' ':
                    break;
                // 碰到'(',push到棧
                case '(':
                    stack.push(c);
                    break;
                // 碰到'+''-',將棧中全部運算符彈出,送到輸出隊列中
                case '+':
                case '-':
                    while (stack.size() != 0) {
                        temp = stack.pop();
                        if (temp == '(') {
                            stack.push('(');
                            break;
                        }
                        suffix += " " + temp;
                    }
                    stack.push(c);
                    suffix += " ";
                    break;
                // 碰到'*''/',將棧中全部乘除運算符彈出,送到輸出隊列中
                case '*':
                case '/':
                    while (stack.size() != 0) {
                        temp = stack.pop();
                        if (temp == '(' || temp == '+' || temp == '-') {
                            stack.push(temp);
                            break;
                        } else {
                            suffix += " " + temp;
                        }
                    }
                    stack.push(c);
                    suffix += " ";
                    break;
                // 碰到右括號,將靠近棧頂的第一個左括號上面的運算符所有依次彈出,送至輸出隊列後,再丟棄左括號
                case ')':
                    while (stack.size() != 0) {
                        temp = stack.pop();
                        if (temp == '(')
                            break;
                        else
                            suffix += " " + temp;
                    }
                    // suffix += " ";
                    break;
                //若是是數字,直接送至輸出序列
                default:
                    suffix += c;
            }
        }

        //若是棧不爲空,把剩餘的運算符依次彈出,送至輸出序列。
        while (stack.size() != 0) {
            suffix += " " + stack.pop();
        }
        return suffix;
    }
}

//計算後綴表達式的值

import java.util.*;
public class suffixToArithmetic{
    int suffixToArithmetic(String h) {
        Stack<Integer>stack = new Stack<Integer>();
        String b[] = h.split(" ");//將字符串轉化爲字符串數組
        for(int i=0;i<b.length;i++){
            String c = b[i];
            if((c.equals("+")||c.equals("-"))||(c.equals("*")||c.equals("÷"))){
                int y = stack.pop();
                int x = stack.pop();
                Caculate z = new Caculate();
                                stack.push(z.Caculate(x,y,c));//將運算結果從新壓入棧
            }//是運算符,彈出運算數,計算結果
            else{
                stack.push(Integer.valueOf(c));
            }
        }
        return stack.pop();//彈出棧頂元素就是運算最終結果
    }
}

//斷定運算符並進行運算

class Caculate{
    int Caculate(int x,int y,String c) {
        if (c.equals("+"))
            return x + y;
        if (c.equals("-"))
            return x - y;
        if (c.equals("*"))
            return x * y;
        if (c.equals("/")){
        if(x<=y||x==0) return 1;
        else return x / y;
    }
    return 0;
    }
}

四則運算連接:碼雲連接

3、總結分析與運行截圖

結對項目總結與分析

咱們開始的時候,都沒有太注重這個項目,以爲它不難。可是在作起這個項目時,咱們就發現本身錯了————這個項目並不簡單。相反,它仍是很複雜的。這也讓咱們知道了爲什麼它是結對項目了,而不是我的項目。在作這個項目的時候,咱們遇到最大的問題就是缺乏這一塊的知識,因此咱們不得不邊學邊作。所以,在編程中咱們遇到了不少問題,包括往中綴表達式加入括號的問題,以及除法計算的問題,遇到左右括號數量不等的狀況,遇到括號只括住一個數字或者一個運算符的問題,遇到碰見除法沒法輸出的問題,遇到沒法計算出結果的問題。幸虧,個人搭檔很是厲害,這些大多數都是個人搭檔張智敏解決的,可是依舊有個問題沒有解決,就是除法計算問題:
截圖

(關於UML圖,咱們暫時還未弄好,在後面的結對項目中咱們會補上)

代碼運行截圖

四則運算簡版運行截圖:

四則運算運行截圖:

4、結對同伴的評價

在此次項目中,個人搭檔張智敏同窗是駕駛員的身份,而我是領航員的身份。在此次項目中,個人搭檔充分體現了駕駛員的身份,全部代碼都是他操控鍵盤打出來的。而且在遇到問題的時候,他都分析得很仔細認真,因此大多數問題都是他先想出解決辦法並最後解決的,因此我認爲個人搭檔很是棒。在之後的項目中,咱們會合做得更好,但願我能幫到個人搭檔更多,爭取把咱們的項目作得更好。

5、代碼託管

代碼託管

相關文章
相關標籤/搜索