結果チームプログラミングを達成--java

1、GitHubの住所:https://github.com/caiyouling/Myapp

チームメイト:忠Xiaomin GitHubの住所:https://github.com/zhongxiao136/Myapp

2.PSPテーブル

PSP パーソナルソフトウェアプロセス段階 それがかかると予想される(分) 実際の時間がかかる(分)
プランニング 計画 40 30
.Estimate このタスクが必要とどのくらいの時間の推定 40 30
開発 開発 1320 1330
。分析 需要分析 100 120
.Designスペック 設計ドキュメントの生成 40 30
.Designレビュー デザインレビュー 15 20
.Coding標準 コードの仕様 15 20
。設計 具体的な設計 90 100
。コーディング 具体的なコーディング 850 950
.CODEレビュー コードレビュー 90 90
。テスト 検査(セルフテスト、コードを変更し、変更を提出) 120 130
報告 レポート 180 160
。試験報告書 テストレポート 90 80
.Size測定 計算ワークロード 30 40
.Postmortem&プロセス改善計画 その後まとめ、およびプロセス改善計画 60 40
トータル 1540 1520

効果分析

設計と実装プロセス

  • ソリューションの概要:4つの基本算術の問題を自動的に生成題したとして、ランダムな発現系を生成する必要があります。式は、演算子とオペランドを含むので、我々は式にcreateExpressionと回答を使用して、そのクラスの組成物、ランダムに生成さCreateNumAndOpeクラスを使用した(計算式を用いて計算し、結果は適切な分数または整数であるので、私たちは、分数を使用します最終形態にクラス小数演算)し、その後のCreateFileクラスでタイトルを生成し、質問に答えると、ファイルを作成し、最後に、グレードクラスの答えを確認し、結果ファイルを生成します。
  • createNumAndOpeカテゴリ:オペレータ定義アレイ; createNumber()とcreateOperator()を含む場合に(ランダムに生成された整数または分数を用いてランダムクラス)番号を生成するように動作可能createNumber(); createOperator()演算子、からランダムオペレータを生成しますアレイは、オペレータが選択しました。
  • createExpressionクラス:exerciseAndAnswer()配列オペランドとオペレータアレイが必要ランダムクラスブラケットがランダムに生成されたかどうかを決定するために、そして最終的に計算は()の結果を計算し、前記計算式、に基づいて生成された前記ランダム括弧表現を生成します。getExerciseAndAnswer()は、対応するタイトル番号と回答し、ユーザにより入力されたトピックによる数値範囲を生成します。
  • カテゴリを計算します。そして、文字配列への発現、1つのトラバースずつ、と後置式に中置式を使用してオペレータスタックオペランドスタックを確立するために評価されます。
  1. 最も優先順位の高いブラケットので、我々は最初の「(」か否かを判定し、もしスタックのオペレータ。
  2. 「か否かを判断する(」演算子の後にあり、その結果は、オペランドスタックに再度格納され、スタックは、左括弧である「)と、2つのオペランドから取得さを算出します」。
  3. 演算子の優先順位演算子はトップエレメント未満である場合、スタックの上部が、オペレータの優先順位よりも高くなくなるまで、その後、操作2つのオペランドを取るオペレータか否かを判断し、結果が計算次いで、オペランドスタックに格納されます。オペレータスタック。
  4. 操作の数がスコアを生成したが、我々は文字の配列になっているため、オペランドは、あなたがに「/」が必要な場合は、分子と分母を取得するためのフラグとして整数の場合、我々は分母になる1にセットされ、オペランドがに従って変換され、スコアの計算は、()を算出する到達し、その結果を返します
  • フラクションクラス:分取操作であって、前記適切な画分不適切な画分に最大公約数、getRealFraction()を生成するために、ユークリッドアルゴリズムを用いて、GCD()最終的な分数を生成するためgetFinalFraction()。
  • CREATEFILEカテゴリ:BufferedWriterのタイトル、ファイルの書き込みによってPRINTFILEを生成し、現在のフォルダのパスを取得するにはSystem.getProperty()を使用し、応答ファイル応答ファイル(ユーザーの回答)、フォルダPRINTFILEに保存されています
  • グレードクラス:ユーザーの回答を認証するための正しいです、タイトル番号と書き込みグレード文書のタイトルの計算された数のファイルとWriterの回答文書がBufferedReaderのを使用して比較することができます読み込み、正しいか間違って、そこPRINTFILEフォルダ。
  • 次のようにさまざまな種類の間で呼び出します:
  • Frameクラス:グラフィカルなインターフェイスは、演習用ファイルが生成されます、ユーザーがクリック「ファイルを生成」は、タイトルが左側のパネルに表示され、中央のパネルの答えは、答えを見るためにクリックして、結果を確認するには、右サイドパネルの正しい答えがあるでしょうこれは、ボックススコアをポップアップ表示されます。

キーコード説明

  • オペランドと演算子を生成するための方法:1ランダムに生成されたフラグを使用= [0,1]、フラグが0である場合、整数2フラグを生成する場合は、フラクショナル組成物を生成するために、分子と分母1
public static String[] createNumber(int number, int round){

        Random random = new Random();
        String[] num = new String[number];

        for (int i = 0; i < number; i++) {
            //用于判断生成整数还是分数
            int flag = (int)(Math.random()*10) % 2;
            if(flag == 0){          //生成整数
                int n = random.nextInt(round);
                if(n == 0){
                    num[i] = 1 + "";
                }else{
                    num[i] = n +"";
                }
            }else{          //生成分数
                //随机生成分子和分母
                int numerator = random.nextInt(round);
                int denominator = random.nextInt(round);;
                while(numerator>=denominator || numerator==0 || denominator==0){    //判断是否为真分数,且不能生成带0的分数
                    numerator = random.nextInt(round);
                    denominator = random.nextInt(round);
                }
                //拼装成分数形式
                num[i] = numerator + "/" + denominator;
            }
        }
        return num;
    }

    /**
     * 随机生成运算符
     * 将四则运算符放入一个静态不可变的operatorTypes[]字符数组中
     * 随机产生index到数组中取操作符
     */
    private static final Character[] operatorTypes = {'+' , '-' , '×' , '÷'};

    public static Character[] createOperators(int number) {
        Character[] operators = new Character[number];
        for (int i = 0; i < number; i++) {
            //随机获取运算符的类型(0~3 代表4个运算符(+、-、×、÷)的类型)
            int index = (int)(Math.random()*4);
            Character operatorType = operatorTypes[index];
            operators[i] = operatorType;
        }
        return operators;
    }
     public static int priority(Character character) {
        switch(character) {

            case '×':
            case '÷':return 1;
            case '+':
            case '-':return 0;
        }
        return -1;
    }
    
     private static String[] exerciseAndAnswer(String[] numbers, Character[] operators){

        Random random = new Random();
        //获得操作数的数量
        int num = numbers.length;
        //随机生成带括号的算式
        int isAddBracket = (int)(Math.random()*10) %2;
        if(isAddBracket ==  1){    //当isAddBracket==1时,生成带括号的表达式
            //当标记为1时代表该操作数已经添加了左括号
            int[] leftBracket = new int[num];
            //当标记为1时代表该操作数已经添加了右括号
            int[] rightBracket = new int[num];
            //遍历操作数数组,随机添加括号
            for (int index = 0 ; index<num-1 ; index++) {
                int n = (int)(Math.random()*10)%2;
                if(n == 0 && rightBracket[index] != 1) {//判断当前操作数是否标记了左括号
                    leftBracket[index] = 1;     //标记已生成左括号
                    numbers[index] = "(" + numbers[index];  //操作数之前加上左括号
                    int k = num - 1;
                    //生成右括号的位置(左括号的位置~最后)
                    int rightBracketIndex = random.nextInt(k)%(k-index) + (index+1);
                    //如果当前操作数有左括号,则重新生成括号位置
                    while (leftBracket[rightBracketIndex] == 1){
                        rightBracketIndex = random.nextInt(k)%(k-index) + (index+1);
                    }
                    rightBracket[rightBracketIndex] = 1;        //标记已生成右括号
                    numbers[rightBracketIndex] = numbers[rightBracketIndex] +")";
                }
            }
        }
        //将运算符数组和操作数数组交替拼成一个算式字符串
        StringBuilder str = new StringBuilder(numbers[0]);
        for (int k = 0; k < operators.length; k++) {     //组成算式
            str.append(operators[k]).append(numbers[k + 1]);
        }
        //将算式转换为String
        String exercise = str.toString();
        //获取运算式结果
        String answer = Calculate.getAnswer(exercise);
        if(answer.equals("-")){      //运算过程出现负数则返回null
            return null;
        }
        return new String[]{exercise,answer};
    }
public static String getAnswer(String expression) {

        Stack<Character> operators = new Stack<Character>();  //运算符栈,用于存放运算符
        Stack<Fraction> fractions = new Stack<Fraction>();  //操作数栈,用于存放操作数
        if(expression == null){
            return "null";
        }
        char[] chars = expression.toCharArray();   //将表达式字符串转成字符数组
        //遍历获取处理
        for (int i = 0 ; i<chars.length ; i++) {
            char c = chars[i];
            if(c == '('){             //先处理有括号的情况,如果是左括号,入栈
                operators.push(c);
            }   else if(c == ')'){           //当前字符为右括号
                while(operators.peek() != '('){   //当运算符栈顶的元素不为‘(’,则继续

                    Fraction fraction1 = fractions.pop();   //拿取操作栈中的两个分数
                    Fraction  fraction2 = fractions.pop();
                    //获取计算后的值
                    Fraction result = calculate(operators.pop(), fraction1.getNumerator(), fraction1.getDenominator(),
                            fraction2.getNumerator(), fraction2.getDenominator());
                    if(result.getNumerator()<0){            //判断是否为负数
                        return  "-";
                    }
                    //将结果压入栈中
                    fractions.push(result);
                }
                //将左括号出栈
                operators.pop();
            }else if(isOperator(c)){//是运算符
                //当运算符栈不为空,且当前运算符优先级小于栈顶运算符优先级
                while(!operators.empty() && !(priority(c)>= priority(operators.peek()))){
                    //拿取操作栈中的两个分数
                    Fraction fraction1 = fractions.pop();
                    Fraction  fraction2 = fractions.pop();
                    //获取计算后的值
                    Fraction result = calculate(operators.pop(), fraction1.getNumerator(), fraction1.getDenominator(),
                            fraction2.getNumerator(), fraction2.getDenominator());
                    if(result.getNumerator()<0){
                        return  "-";
                    }
                    //将结果压入栈中
                    fractions.push(result);
                }
                //将运算符入栈
                operators.push(c);
            }else{          //是操作数
                if(c >= '0' && c <= '9'){
                    StringBuilder fra = new StringBuilder();
                    //对分式进行处理
                    while(i<chars.length && (chars[i]=='/' || ((chars[i]>='0') && chars[i]<='9'))){
                        fra.append(chars[i]);
                        i++;
                    }
                    i--;
                    //到此 fra里面是一个操作数
                    String val = fra.toString();
                    //标记‘/’的位置
                    int flag = val.length();
                    for(int j = 0 ; j<val.length() ; j++){
                        if(val.charAt(j)=='/'){//当获取的数值存在/则标记/的位置,便于接下来划分分子和分母生成分数对象
                            flag = j;
                        }
                    }
                    //把操作数拆成分式计算
                    //分子
                    StringBuilder numeratorBuf = new StringBuilder();
                    //分母
                    StringBuilder denominatorBuf = new StringBuilder();
                    for(int k = 0 ; k<flag; k++){
                        numeratorBuf.append(val.charAt(k));
                    }
                    //判断是否为分数
                    if(flag != val.length()){
                        for(int m = flag+1 ; m<val.length() ; m++){
                            denominatorBuf.append(val.charAt(m));
                        }
                    }else{//如果不是分数则分母计为1
                        denominatorBuf.append('1');
                    }
                    //将分子分母分别入栈
                    fractions.push(new Fraction(Integer.parseInt(numeratorBuf.toString()),
                            Integer.parseInt(denominatorBuf.toString())));
                }
            }
        }
        while(!operators.empty() && fractions.size()>1){

            Fraction fraction1 = fractions.pop();
            Fraction  fraction2 = fractions.pop();
            //获取计算后的值
            Fraction result = calculate(operators.pop(), fraction1.getNumerator(), fraction1.getDenominator(),
                    fraction2.getNumerator(), fraction2.getDenominator());
            if(result.getNumerator()<0){
                return "-";
            }
            //将结果压入栈中
            fractions.push(result);
        }
        //计算结果
        Fraction result = fractions.pop();
        //获取最终的结果(将分数进行约分)
        return Fraction.getFinalFraction(result);
    }
    //用于验证答案是否正确,correct的题数用字符串拼接,再分割字符串
     public static void isAnswer(String writeFilePath, String answerFilePath) {
        //获取用户答题和练习答案的文件
        File writeFile = new File(writeFilePath);
        File answerFile = new File(answerFilePath);
        //找到存放Writer.txt和Answer.txt文件的文件夹
        String fileDirectory = System.getProperty("user.dir") + File.separator + "PrintFile";
        File gradeFile = new File(fileDirectory, "Grade.txt");//在当前文件夹下生成Grade.txt文件
        if(writeFile.isFile() && answerFile.isFile()) {
            try {
                BufferedReader writeReader = new BufferedReader(new InputStreamReader(new FileInputStream(writeFile)));
                BufferedReader answerReader = new BufferedReader(new InputStreamReader(new FileInputStream(answerFile)));
                //储存错题和对题
                String correct = "";
                String wrong = "";
                int correctNum = 0;
                int wrongNum = 0;
                //记录错题对题的题号
                int index = 1;
                String write = null;
                String answer = null;
                System.out.println("开始验证答案···");
                //通过一行行读取文件比较答题情况
                while((( write= writeReader.readLine()) != null) && ((answer = answerReader.readLine()) != null)){
                    if(write.equals(answer)){
                        //将答对的题用字符串拼接
                        correct += "," + index;
                        index ++;
                        correctNum ++;
                    }else{
                        wrong += "," + index;
                        index ++;
                        wrongNum ++;
                    }
                }
                //用于生成Grade.txt文件内容
                if(correctNum > 0){
                    correct = "Correct: " + correctNum + "(" + correct.substring(1) +")" + "\r\n" ;
                }else{
                    correct = "Correct: 0" +"\r\n";
                }
                if(wrongNum > 0){
                    wrong = "Wrong: " + wrongNum +  "(" + wrong.substring(1) +")";
                }else{
                    wrong = "Wrong: 0";
                }
                //写入文件
                BufferedWriter gradeFileBuf = new BufferedWriter(new FileWriter(gradeFile));
                gradeFileBuf.write(correct);//将correct 和wrong写入文件
                gradeFileBuf.write(wrong);
                System.out.print(correct);//控制台也打印答题情况
                System.out.println(wrong);
                if(writeReader != null){
                    writeReader.close();
                }
                if(answerReader != null){
                    answerReader.close();
                }
                if(gradeFileBuf != null){
                    gradeFileBuf.close();
                }
                 public static String getFinalFraction(Fraction fraction) {
        int denominator = fraction.getDenominator();        //获得分子分母
        int numerator = fraction.getNumerator();
        if(numerator == 0){ //若分子为0,则输出0
            return "0";
        }
        if(denominator == 0){
            return "";
        }
        int a = gcd(numerator, denominator);        //c是分子分母的最大公因数,将分子分母化简
        if (denominator == 1 ) {   //分母为1
            return numerator + "";
        }
        if(numerator == denominator){
            return 1+"";
        }else {
            if(numerator > denominator){           //分子大于分母化为真分数
                fraction = getRealFraction(fraction);   //假分数分割为商和余数,余数作为新的分子
                if(fraction.getNumerator() == 0){//若余数为0,则代表整除
                    return fraction.getInter()+"";
                }else {
                    return fraction.getInter() + "'" + fraction.getNumerator()/a + "/" + fraction.getDenominator()/a;
                }
            }else{              //其他情况化简分数
                return numerator/a + "/" + denominator/a;
            }
        }
    }
    private static int gcd(int numerator, int denominator){
        if(numerator%denominator == 0){
            return denominator;         //获取最大公因数
        }else{
            return gcd(denominator,numerator%denominator);    //辗转相除法递归获取最大公因数
        }
    }

テスト

1.メインを起動し、コンソールの印刷実行

リストファイルには、2ユーザの入力に生成

3.トピックのタイトルファイルを生成

ファイルに答えを生成する4.

5.場合は、応答ファイルの答

6.再回答決意

7.着信パラメータが間違って

入力ファイル名が正しくない8.

9.1万対象生成

被写体が1万応答ファイル生成10.

11.初期インターフェース

12は、クリックファイル生成

入力発電機の数13

14は、対象を生成する

15 。実施解答

16.出力結果

17 10個の質問生成

1万を生成18

概要

  • 本次结对项目中,我们都受益匪浅,结对项目需要多次讨论得出一致结论,两个人一起分析问题解决bug是比一个人好一些,虽然也有发生歧义的地方,但是不同角度看问题,才能实现1+1>2,这次编程作业让我们对java有了更深了了解,但也还有很多不足的

おすすめ

転載: www.cnblogs.com/you-ling/p/11689663.html