軟件工程做業02

 

  1.設計思想:java

                   針對新的要求:是否有乘除法; 是否有括號(最多能夠支持十個數參與計算); 數值範圍; 加減有無負數; 除法有無餘數!在建立新數組根據不一樣的需求進行選擇。利用random隨機生成操做數,構造運算式時添加「(」、「)」,建立expressCalculate方法進行計算,建立priorityCompare方法利用棧判斷優先級。再建立隨機生成括號和運算符的方法,構造Fenshu類,建立約簡等方法。最後在main函數里根據建立的數組長度進行循環輸出。express

 

 2.源代碼:數組

import java.util.Random;
import java.util.Scanner;
import java.util.Stack;



public class SiZe1
{

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner scan = new Scanner(System.in);
        System.out.println("0、整數式   一、分數式");
        int type = scan.nextInt();
        System.out.println("生成的運算式個數:");
        int n = scan.nextInt();
        System.out.println("是否有乘除法(1有,0沒有)");
        int hasChengChu = scan.nextInt();
        System.out.println("是否有括號(1有,0沒有)");
        int hasKuoHao = scan.nextInt();
        System.out.println("加減有無負數(1有,0沒有)");
        int hasFuShu = scan.nextInt();
        System.out.println("除法有無餘數(1有,0沒有)");
        int hasYuShu = scan.nextInt();
        System.out.println("數值範圍(最大數)");
        int maxNum = scan.nextInt();
        String[] yunSuanShiArray = createYunSuanShi(hasChengChu, hasKuoHao, hasFuShu, hasYuShu, maxNum, n, type);
        for(int i = 0;i < yunSuanShiArray.length;i++){
            System.out.println(yunSuanShiArray[i]);
        }
        scan.close();
    }
    
    
    //生成整數計算式添加限制條件,type爲運算式類型  0表明整數式,1表明真分數式
    public static String[] createYunSuanShi(int hasChengChu,int hasKuoHao,int hasFuShu,int hasYuShu,int maxNum,int n,int type) {
        int i = 0;
        String yunSuanShiTemp;
        String[] yunSuanShiArray = new String[n];
        int operatorScope = 2 + 2 * hasChengChu;//運算符範圍,2或4,2表明只有加減,4表明有加減乘除
        int length;
        String[] operatorArray = {"+","-","*","/"};
        String[] operatorNum = null;//存儲運算數
        int num_index;//運算數下標
        String[] operatorSymbol = null;//存儲運算符
        int symbol_index;//運算符下標
        int[] brackets = null;//存儲括號個數
        
        while(i < n) {
            length = Integer.parseInt(getOperatorNumber(0, 9)) + 2;//計算式運算數長度
            operatorNum = new String[length];
            operatorSymbol = new String[length - 1];
            num_index = 0;
            symbol_index = 0;
            operatorNum[num_index++] = getOperatorNumber(type, maxNum);//隨機生成操做數
            for(int j = 0;j < length - 1;j++){
                operatorSymbol[symbol_index++] = operatorArray[Integer.parseInt(getOperatorNumber(0, operatorScope))];//隨機生成操做符
                operatorNum[num_index++] = getOperatorNumber(type, maxNum);//隨機生成操做數
            }        
            if(hasKuoHao == 1){
                brackets = randomAddBracket(length);//生成括號數組
            }
            //構造運算式
            yunSuanShiTemp = "";
            for(int j = 0;j < length;j++){
                //添加左括號
                if(hasKuoHao == 1){
                    for(int k = 0;k < brackets[j];k++){
                        yunSuanShiTemp += "(";
                    }
                }
                yunSuanShiTemp += " " + operatorNum[j] + " ";//加上運算數
                
                //添加右括號
                if(hasKuoHao == 1){
                    for(int k = 0;k > brackets[j];k--){
                        yunSuanShiTemp += ")";
                    }
                }
                //若是不是最後一個運算數則要加上運算符
                if(j != length - 1){
                    yunSuanShiTemp += operatorSymbol[j];
                }
            }
            
            //計算結果
            String answer = expressCalculate(yunSuanShiTemp, hasFuShu, hasYuShu, type, length - 1);
            if((answer.equals("ERROR"))){
                continue;
            }
            yunSuanShiTemp += "=" + answer;
            //檢驗重複
            boolean chongFu = false;
            for(int j = 0;j < i;j++){
                if((yunSuanShiArray[j].equals(yunSuanShiTemp))){
                    chongFu = true;
                    break;
                }
            }
            if(chongFu == false){
                yunSuanShiArray[i++] = yunSuanShiTemp;
            }
        }
        return yunSuanShiArray;
    }
    
    //表達式計算,參數爲字符串類型的運算式
    public static String expressCalculate(String express,int hasFuShu,int hasYuShu,int type,int symbolNum){
        Stack<String> num = new Stack<String>();
        Stack<String> symbolS = new Stack<String>();
        symbolS.push("#");
        express += "#";
        char ch;
        int i = 0;
        int s = 0;
        ch = express.charAt(i);
        while(s < symbolNum){
            if(ch == ' '){//讀到空格,說明開始讀運算數
                String readNumStr = "";
                while(true){
                    ch = express.charAt(++i);
                    if(ch == ' '){
                        break;
                    }
                    readNumStr += ch;
                    
                }
                if((i + 1) < express.length()){
                    ch = express.charAt(++i);
                }
                num.push(readNumStr);
            }else{//讀到的是運算符
                char compare = priorityCompare(symbolS.peek(),ch + "");
                
                if(compare == '='){//若是是右括號
                    symbolS.pop();
                    ch = express.charAt(++i);
                }else if(compare == '>'){//ch的優先級小於棧頂的優先級     比棧頂的優先級高就不算,入棧,低就彈棧運算
                    //彈出兩個運算數,彈出一個運算符
                    String bStr = num.pop();
                    String aStr = num.pop();
                    String symbolT = symbolS.pop();
                    String c = yunSuan(aStr,bStr,symbolT,hasFuShu,hasYuShu,type);
                    if(c.equals("ERROR")){
                        return "ERROR";
                    }else if(c.indexOf("餘") >= 0 && s != symbolNum - 1){//有餘數
                        return "ERROR";
                    }else{
                        num.push(c);
                    }
                    s++;
                }else{
                    symbolS.push(ch + "");
                    if((i + 1) < express.length()){
                        ch = express.charAt(++i);
                    }
                }
            
            }
        }
        return num.pop();
    }
    
    public static String yunSuan(String aStr,String bStr,String symbol,int hasFuShu,int hasYuShu,int type){
        if(type == 0){//整數
            int a = Integer.parseInt(aStr);
            int b = Integer.parseInt(bStr);
            if(symbol.equals("+")){
                return "" + (a + b);
            }else if(symbol.equals("-")){
                if(a - b < 0 && hasFuShu == 0){
                    return "ERROR";
                }else{
                    return "" + (a - b);
                }
            }else if(symbol.equals("*")){
                return "" + (a * b);
            }else{
                if(b == 0){
                    return "ERROR";
                }
                if(a % b == 0){
                    return "" + (a / b);
                }else{
                    if(hasYuShu == 1){
                        return (a / b) + "餘" + (a % b);
                    }else{
                        return "ERROR";
                    }
                }
            }
        }else{//分數
            String[] af = aStr.split("/");
            String[] bf = bStr.split("/");
            if(af[0].equals("0") || bf[0].equals("0")){
                return "ERROR";
            }
            FenShu a = new FenShu(Integer.parseInt(af[1]),Integer.parseInt(af[0]));
            FenShu b = new FenShu(Integer.parseInt(bf[1]),Integer.parseInt(bf[0]));
            if(symbol.equals("+")){
                return a.add(b).toString();
            }else if(symbol.equals("-")){
                FenShu c = a.subtract(b);
                if(hasFuShu == 1 && c.getNumerator() < 0){
                    return "ERROR";
                }
                return c.toString();
            }else if(symbol.equals("*")){
                return a.multiply(b).toString();
            }else{
                return a.divide(b).toString();
            }
        }
    }    
    //判斷優先級
    public static char priorityCompare(String a,String b){
        char[][] priority = {
                {'>','>','<','<','<','>','>'},
                {'>','>','<','<','<','>','>'},
                {'>','>','>','>','<','>','>'},
                {'>','>','>','>','<','>','>'},
                {'<','<','<','<','<','=','>'},
                {'>','>','>','>',' ','>','>'},
                {'<','<','<','<','<',' ','='}
        };
        int a_index = index_symbol(a);
        int b_index = index_symbol(b);
        return priority[a_index][b_index];
    }
    
    public static int index_symbol(String a){
        String p = "+-*/()#";
        return p.indexOf(a);
    }
    
    //隨機生成括號,參數爲運算式的運算數的個數
    public static int[] randomAddBracket(int length){
        int[] brackets = new int[length];
        for(int i = 0;i < brackets.length;i++)   brackets[i] = 0;
        Random rd = new Random();
        for(int i = 2;i < length;i++){//添加的括號長度(括號包圍的運算數的個數)
            for(int j = 0;j < length - i + 1;j++){
                int t = rd.nextInt(2);//隨機生成0或1,0表明不加括號,1表明加括號
                if(t == 1){
                    if(brackets[j] >= 0 && brackets[j + i - 1] <= 0){//要加的括號的第一個運算數週圍沒有右括號,且 最後一個運算數週圍沒有左括號
                        int counteract = 0;
                        for(int k = j;k < j + i;k++){//將要加的括號之間的全部運算數對應的brackets相加,
                                                        //若是和爲0說明這個括號之間的括號是匹配的,不會出現括號交叉現象
                            counteract += brackets[k];
                        }
                        if(counteract == 0){
                            brackets[j]++;
                            brackets[j + i - 1]--;
                        }
                    }
                }
            }
        }
        return brackets;
    }
    
    //隨機生成一個運算數(                type==0表明生成整數,type==1表明生成真分數,maxNum表明數值範圍 0-(maxNum-1)               )
    public static String getOperatorNumber(int type,int maxNum){
        Random rd = new Random();
        int a;
        while(true){
            a = rd.nextInt(maxNum);
            if(type == 0){//隨機生成一個整數
                return "" + a;
            }else{//隨機生成一個真分數
                if(a == 0){
                    continue;
                }
                int b = rd.nextInt(a);
                FenShu c = new FenShu(a,b);
                return c.toString();
            }
        }
    }
    


}







class FenShu {
    private int denominator,numerator;

    public int getDenominator() {
        return denominator;
    }

    public void setDenominator(int denominator) {
        this.denominator = denominator;
    }

    public int getNumerator() {
        return numerator;
    }

    public void setNumerator(int numerator) {
        this.numerator = numerator;
    }

    public FenShu(int denominator, int numerator) {
        this.denominator = denominator;
        this.numerator = numerator;
        yueJian();
    }
    
    FenShu(){}
    
    //約簡
    public void yueJian(){
        int y = 1;
        for(int i = numerator;i > 1;i--){
            if(numerator % i == 0 && denominator % i == 0){
                y = i;
                break;
            }
        }
//        int nc = numerator,dc = denominator;
//        if(nc != 0){
//            while(nc != dc - nc){
//                y = dc - nc;
//                if(nc > y){
//                    dc = nc;
//                    nc = y;
//                }else{
//                    dc = y;
//                }
//            }
//            y = nc;
//    
            numerator /= y;
            denominator /= y;
        
    }
    
    //
    public FenShu add(FenShu b){
        FenShu c = null;
        int nNumerator = this.numerator * b.getDenominator() + this.denominator * b.getNumerator();
        int nDenominator = this.denominator * b.getDenominator();
        c = new FenShu(nDenominator,nNumerator);
        return c;
    }
    
    //
    public FenShu subtract(FenShu b){
        FenShu c = null;
        int nNumerator = this.numerator * b.getDenominator() - this.denominator * b.getNumerator();
        int nDenominator = this.denominator * b.getDenominator();
        c = new FenShu(nDenominator,nNumerator);
        return c;
    }
    
    //
    public FenShu multiply(FenShu b){
        FenShu c = null;
        int nNumerator = this.numerator * b.getNumerator();
        int nDenominator = this.denominator * b.getDenominator();
        c = new FenShu(nDenominator,nNumerator);
        return c;
    }
    
    //
    public FenShu divide(FenShu b){
        FenShu c = null;
        int nNumerator = this.numerator * b.getDenominator();
        int nDenominator = this.denominator * b.getNumerator();
        c = new FenShu(nDenominator,nNumerator);
        return c;
    }
    
    //輸出分數形式
    public String toString(){
        if(numerator != 0){
//            if(numerator % denominator == 0)
//                return "" + numerator / denominator;
            return numerator + "/" + denominator;
        }
        return "0";
    }
    
}

 

  3.運行結果截圖dom

 

項目計劃總結:ide

日期\任務 聽課 編寫程序 查閱資料 日總計
星期一 2 2 1 4
星期二     1 1
星期三   2 1 3
星期四 2 2   4
星期五   3 1 4
星期六   3   5
星期日        
周總計 4 12 4

21函數

時間記錄日誌:this

日期 開始時間 結束時間 中斷時間 靜時間 活動 備註
3/7 14:00 15:50 10 100 編寫 編寫程序
  19:30 21:30 20 100 編寫 編寫程序
3/8 19:20 21:30 10 120 編寫 編寫程序 
3/9            
  19:20 20:00 0 40 編寫  
3/10 14:00 15:50 10 100 聽課 軟件工程
  19:20 20:20   60 編寫 調試程序
3/11 18:10 21:30 20 100 編寫 調試程序
             
3/12            
  16:00 17:00   60 博客 撰寫博客

缺陷記錄日誌:編碼

日期 編號 引入階段 排除階段 修復時間&問題描述
3/7 1 編碼 編譯 30min,理清分數
3/8        
3/9        
3/10-3/11 2 編碼 編譯 2hour,調試調試
3/11-3/12 3 編碼 編譯 2hour,完善括號
相關文章
相關標籤/搜索