JJYdesu

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

java实现四则运算程序

github传送门:https://github.com/JJYdesu/operation   

成员:赖展飞 江家懿


 

一、项目要求

实现一个自动生成小学四则运算题目的命令行程序。(实现)

1. 使用 -n 参数控制生成题目的个数。(实现)

 

2. 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围。(实现)

 

3. 生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1 − e2的子表达式,那么e1 ≥ e2(实现)

 

4. 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数(实现)

 

5. 每道题目中出现的运算符个数不超过3个。(实现)

 

6. 任何两道题目不能通过有限次交换+×左右的算术表达式变换为同一道题目(实现)

 

7、生成的题目存入执行程序的当前目录下的Exercises.txt文件,计算答案并存入执行程序的当前目录下的Answers.txt文件。(实现)


 

二、PSP

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

30

50 

· Estimate

· 估计这个任务需要多少时间

30

50 

Development

开发

1450

1430

· Analysis

· 需求分析 (包括学习新技术)

 60

 50

· Design Spec

· 生成设计文档

30 

20 

· Design Review

· 设计复审 (和同事审核设计文档)

30 

30 

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

30 

30 

· Design

· 具体设计

100 

100 

· Coding

· 具体编码

1000 

1200 

· Code Review

· 代码复审

100 

100 

· Test

· 测试(自我测试,修改代码,提交修改)

100 

100 

Reporting

报告

130 

120 

· Test Report

· 测试报告

 50

60 

· Size Measurement

· 计算工作量

50 

30 

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

30 

30 

合计

 

 1610

 1600

三、设计说明

 

  • Formula类包含各种运算方法
  • Create类调用Formula类中的方法生成式子
  • Output类调用Create类打印式子,调用Formula类计算答案,将题目与答案存储到文件中

四、关键代码

Formula类

package formula;


import java.util.ArrayList; public class Formula { public static enum Operators { ADD, // SUB, // MUL, // DIV // } public Operators operator = Operators.ADD; // 实际运算符,用于运算。 public int integer = 0; // 整数部分 public int numerator = 0; // 分子 public int denominator = 1; // 分母 public int symbol = 1; // 代表正负 public ArrayList<Formula> list; // 多项式 /** * 初始化空单项式 */ public Formula() { list = null; } /** * 初始化单项式 */ public Formula(Operators operator) { this.operator = operator; list = null; } /** * 生成自然数单项式 * @param operator 运算符 * @param integer 整数部分 */ public Formula(Operators operator, int integer){ this.operator = operator; if(integer > 0){ this.integer = integer; }else { this.integer = -1 * integer; this.symbol = -1; } list = null; } /** * 生成分数单项式 * @param operator * @param numerator * @param denominator */ public Formula(Operators operator, int numerator, int denominator){ this.operator = operator; this.integer = numerator / denominator; if(numerator * denominator < 0) { // 整数部分 this.symbol = -1; // 数值正负 this.integer = -1 * this.integer; // 正化 } numerator = numerator % denominator; // 求余 numerator = numerator < 0 ? -1 * numerator: numerator; // 正化 denominator = denominator < 0 ? -1 * denominator: denominator; // 正化 if(numerator > 0){ // 约分 int a, b, c; a = denominator; b = numerator; while ((c = a % b) != 0){ a = b; b = c; } this.numerator = numerator / b; this.denominator = denominator / b; } list = null; } /** * 生成单项式 * @param operator 运算符 * @param integer 整数部分 * @param numerator 分子 * @param denominator 分母 */ public Formula(Operators operator, int integer, int numerator, int denominator){ this.operator = operator; if(denominator < 0){ denominator = -1 * denominator; numerator = -1 * numerator; } numerator = integer * denominator + numerator; this.integer = numerator / denominator; if(numerator * denominator < 0) { // 整数部分 this.symbol = -1; // 数值正负 this.integer = -1 * this.integer; // 正化 } numerator = numerator % denominator; // 求余 numerator = numerator < 0 ? -1 * numerator: numerator; // 正化 denominator = denominator < 0 ? -1 * denominator: denominator; // 正化 if(numerator > 0){ // 约分 int a, b, c; a = denominator; b = numerator; while ((c = a % b) != 0){ a = b; b = c; } this.numerator = numerator / b; this.denominator = denominator / b; } list = null; } /** * 生成多项式 * @param operator * @param list */ public Formula(Operators operator, ArrayList<Formula> list){ this.operator = operator; this.list = list; this.injectFormulaValue(); } /** * 无打印 * @return 返回式子字符串 */ public String _print(){ String str = ""; if(list == null || list.size() == 0) { // 单项式 if(numerator > 0 && denominator > 0) str = numerator + "/" + denominator; if(integer > 0) { if(str != "") str = integer + "'" + str; else str = integer + ""; } if(str == "") str = "0"; else if(symbol == -1) str += "( - "+ str +")"; } else { // 多项式 int length = list.size(); for(int i = 0; i < length; i++){ Formula item = list.get(i); if(i == 0) { // 首项 if(item.operator == Operators.SUB) str += " - "; }else { switch (item.operator){ case SUB: str += " - ";break; case ADD: str += " + ";break; case MUL: str += " * ";break; case DIV: str += " ÷ ";break; } } if(item.list != null && item.list.size() > 1) str += '('+ item._print() +')'; else str += item._print(); } } return str; } /** * 控制台输出式子 * @return 式子字符串 */ public String print(){ String str = this._print() + " = "; System.out.println(str); return str; } /** * 记录式子数值 * @param */ public void injectFormulaValue(){ if(list == null) return; int length = list.size(), start = 0, end = 0; if(length < 1) return; // 计算式子值 Formula a, b, c = null; a = new Formula(); for(int i = 0; i < length; i++){ b = list.get(i); if(b.operator == Operators.DIV || b.operator == Operators.MUL){ a = this.mergeValue(a, b); }else { if(c == null) c = a; else c = mergeValue(c, a); a = b; } } c = mergeValue(c, a); // 记录值 this.integer = c.integer; this.numerator = c.numerator; this.denominator = c.denominator; this.symbol = c.symbol; } /** * 合并数值 * @param x * @param y * @return 返回最终数值 */ public Formula mergeValue(Formula x, Formula y){ switch (y.operator){ case MUL: return this._mul(x, y); case DIV: return this._div(x, y); case SUB: return this._sub(x, y); default: return this._add(x, y); } } /** * 加法 * @param x * @param y * @return */ public Formula _add(Formula x, Formula y){ int numerator, denominator, numeratorX, numeratorY; denominator = x.denominator * y.denominator; // 分母 numeratorX = (x.integer * denominator + x.numerator * y.denominator) * x.symbol; // x 分子 numeratorY = (y.integer * denominator + y.numerator * x.denominator) * y.symbol; // y 分子 numerator = numeratorX + numeratorY; // 分子和 return new Formula(x.operator, numerator, denominator); } /** * 减法 * @param x * @param y * @return */ public Formula _sub(Formula x, Formula y){ int numerator, denominator, numeratorX, numeratorY; denominator = x.denominator * y.denominator; // 分母 numeratorX = (x.integer * denominator + x.numerator * y.denominator) * x.symbol; // x 分子 numeratorY = (y.integer * denominator + y.numerator * x.denominator) * y.symbol; // y 分子 numerator = numeratorX - numeratorY; // 分子和 return new Formula(x.operator, numerator, denominator); } /** * 除法 * @param x * @param y * @return */ public Formula _div(Formula x, Formula y){ int numerator, denominator, numeratorX, numeratorY; numeratorX = (x.integer * x.denominator + x.numerator) * x.symbol; numeratorY = (y.integer * y.denominator + y.numerator) * y.symbol; numerator = numeratorX * y.denominator; denominator = numeratorY * x.denominator; return new Formula(x.operator, numerator, denominator); } /** * 乘法 * @param x * @param y * @return */ public Formula _mul(Formula x, Formula y){ int numerator, denominator, numeratorX, numeratorY; Operators operator; numeratorX = (x.integer * x.denominator + x.numerator) * x.symbol; numeratorY = (y.integer * y.denominator + y.numerator) * y.symbol; numerator = numeratorX * numeratorY; denominator = x.denominator * y.denominator; return new Formula(x.operator, numerator, denominator); } /** * 判断正数 * @return Boolean */ public Boolean isPositiveNumber(){ return this.symbol == 1; } /** * 向多项式推入一项 * @param x * @return */ public Boolean push(Formula x){ if(this.list == null) this.list = new ArrayList<Formula>(); int integer, denominator, numerator, symbol; integer = this.integer; denominator = this.denominator; numerator = this.numerator; symbol = this.symbol; this.list.add(x); this.injectFormulaValue(); if(symbol != this.symbol){ // 结果为负数,失败 this.list.remove(list.size() - 1); this.integer = integer; this.denominator = denominator; this.numerator = numerator; this.symbol = symbol; return false; } return true; } /** * 输出算式运算结果字符串 * @return */ public String output(){ String str = ""; if(this.symbol == -1) str += "-"; if(this.integer != 0) str += this.integer; if(this.denominator != 0 && this.numerator != 0) { if(this.integer != 0) str += "'" + this.numerator + "/" + this.denominator; else str += this.numerator + "/" + this.denominator; } if(this.integer == 0 && this.numerator == 0) str = "0"; return str; } /** * 读取字符串 * @param formula * @return */ public static Formula calculateFormulaString(String formula){ if(formula == null) return new Formula(); ArrayList<Formula> stack = new ArrayList<Formula>(); stack.add(new Formula()); Formula target = new Formula(), target2; int length = formula.length(), i = -1, position = 1; char c; Boolean isOk = true; Operators operator = Operators.ADD; while (++i < length){ // System.out.println(i + " | " + length); c = formula.charAt(i); if(c == ' ') continue; else if(c == '('){ stack.add(target); target = new Formula(); } else if(c == ')'){ int index = stack.size() - 1; target2 = stack.remove(index); target2.push(target); target = target2; position = 1; } else if(c == '+' || c == '-' || c == '*' || c == '÷') { stack.get(stack.size() - 1).push(target); switch (c){ case '+': operator = Operators.ADD; break; case '-': operator = Operators.SUB; break; case '*': operator = Operators.MUL; break; case '÷': operator = Operators.DIV; break; } target = new Formula(operator); operator = Operators.ADD; position = 1; }else if(c == '\''){ position = 2; }else if(c == '/'){ if(position == 1){ target.numerator = target.integer; target.integer = 0; } position = 3; target.denominator = 0; } else if(c <= '9' && c >= '0'){ int value = Integer.parseInt(c + ""); if(position == 1){ target.integer = target.integer * 10 + value; }else if(position == 2) { target.numerator = target.numerator * 10 + value; }else if(position == 3) { target.denominator = target.denominator * 10 + value; } }else if(c == '=') break; else { System.out.println("- " + "未识别符号("+ (i+1) +"):"+ c); isOk = false; break; } } // System.out.println("> "+formula); if(isOk){ target2 = stack.get(0); target2.push(target); return stack.remove(0); }else { return new Formula(); } } }

Create类

package formula;
import java.util.*;

public class Create {

        Random r = new Random();
        ArrayList<Formula> list = new ArrayList<Formula>();
        Formula e;

        //生成式子中的第一个操作数(符号只能是+)
        public Formula CreateFirstOperand(int n){
            int a = r.nextInt(n) + 1; //随机产生1-n中的一个操作数
            int h = r.nextInt(n) + 1;
            int g = r.nextInt(h) + 1;
            int b = r.nextInt(2);
            if (b==0){
                e = new Formula(Formula.Operators.ADD, a);
            }
            else {
                e = new Formula(Formula.Operators.ADD, a, g, h);
            }
            return e;
        }

        //生成式子中其他的操作数,可以为+,-,*,/
        public Formula CreateOtherOperand(int n){
            int a = r.nextInt(n) + 1; //随机产生1-n中的一个操作数
            int h = r.nextInt(n) + 1;
            int g = r.nextInt(h) + 1;

            int b = r.nextInt(2);
            int c = r.nextInt(4);
            if(b==0){
                switch (c){
                    case 0:e = new Formula(Formula.Operators.ADD, a);break;
                    case 1:e = new Formula(Formula.Operators.SUB, a);break;
                    case 2:e = new Formula(Formula.Operators.MUL, a);break;
                    case 3:e = new Formula(Formula.Operators.DIV, a);break;
                }
            }
            else{
                switch (c){
                    case 0:e = new Formula(Formula.Operators.ADD, a, g, h);break;
                    case 1:e = new Formula(Formula.Operators.SUB, a, g, h);break;
                    case 2:e = new Formula(Formula.Operators.MUL, a, g, h);break;
                    case 3:e = new Formula(Formula.Operators.DIV, a, g, h);break;
                }
            }
            return e;
        }

        //随机生成多项式
        public  String CreateFormula(int p){

                String s = new String();
                Create n = new Create();
                Formula first,first2,second, third, fourth, i,j,k,l;
                i = new Formula();
                j = new Formula();
                l = new Formula();
                first = n.CreateFirstOperand(p);
                first2 = n.CreateFirstOperand(p);
                second = n.CreateOtherOperand(p);
                third = n.CreateOtherOperand(p);
                fourth = n.CreateOtherOperand(p);
                int OperandNumber = r.nextInt(3);

                switch (OperandNumber) {

                    //两个操作数
                    case 0:
                        i.push(first);
                        i.push(second);
                        s = i._print();
                        break;

                        //三个操作数
                        case 1:
                            i.push(first);
                            i.push(second);
                            i.push(third);
                            s = i._print();
                        break;

                        //四个操作数
                        case 2:
                            int a = r.nextInt(4);
                            switch (a) {
                                case 0:            //a+b+c+d
                                     i.push(first);
                                     i.push(second);
                                     i.push(third);
                                     i.push(fourth);
                                     s = i._print();
                                 break;
                                 case 1:
                                     int b = r.nextInt(2);
                                     switch (b) {
                                         case 0:              //(a+b+c)+d
                                             i.push(first);
                                             i.push(second);
                                             i.push(third);
                                             j.push(i);
                                             j.push(fourth);
                                             s = j._print();
                                         break;
                                         case 1:                //a+(b+c+d)
                                              int c = r.nextInt(3);
                                              switch (c) {
                                                  case 0: k = new Formula(Formula.Operators.ADD);j = k;break;
                                                  case 1: k = new Formula(Formula.Operators.SUB);j = k;break;
                                                  case 2: k = new Formula(Formula.Operators.MUL);j = k;break;
                                              }
                                              i.push(first);
                                              j.push(first2);
                                              j.push(second);
                                              j.push(third);
                                              i.push(j);
                                              s = i._print();
                                              break;
                                 }
                                 break;

                                     case 2:
                                         int c = r.nextInt(3);
                                         int d = r.nextInt(3);
                                         switch (d) {
                                             case 0: k = new Formula(Formula.Operators.ADD);j = k;break;
                                             case 1: k = new Formula(Formula.Operators.SUB);j = k;break;
                                             case 2: k = new Formula(Formula.Operators.MUL);j = k;break;
                                         }
                                         switch (c) {
                                             case 0:              //(a+b)+c+d
                                              i.push(first);
                                              i.push(second);
                                              j.push(i);
                                              j.push(third);
                                              j.push(fourth);
                                              s = j._print();
                                              break;
                                              case 1:              //a+(b+c)+d
                                                  i.push(first);
                                                  j.push(first2);
                                                  j.push(second);
                                                  i.push(j);
                                                  i.push(third);
                                                  s = i._print();
                                                  break;
                                                   case 2:               //a+b+(c+d)
                                                       i.push(first);
                                                       i.push(second);
                                                       j.push(first2);
                                                       j.push(third);
                                                       i.push(j);
                                                       s = i._print();
                                                       break;
                                 }
                                 break;
                                         case 3:       //(a+b)+(c+d)
                                             int e = r.nextInt(3);
                                             switch (e) {
                                                 case 0: k = new Formula(Formula.Operators.ADD);j = k;break;
                                                 case 1: k = new Formula(Formula.Operators.SUB);j = k;break;
                                                 case 2: k = new Formula(Formula.Operators.MUL);j = k;break;
                                             }
                                             i.push(first);
                                             i.push(second);
                                             j.push(first2);
                                             j.push(third);
                                             l.push(i);
                                             l.push(j);
                                             s = l._print();
                                             break;

                            }

                            break;
                }
                return s;

        }
}

Output类

package formula;
import java.io.*;
import java.util.Scanner;

public class Output {
    public static void main(String[] args)throws IOException{
        Create n = new Create();
        Formula b;
        int i, a, r,m;
        String[] t = new String[20000];
        Scanner sc = new Scanner(System.in);
        PrintStream questionout = new PrintStream("exercise.txt");
        PrintStream answerout = new PrintStream("answer.txt");

        System.out.println("请输入数值范围:");
        a = sc.nextInt();
        questionout.print("数字范围:" + a + "\t");
        System.out.println("请输入要生成的题目数量:");
        i = sc.nextInt();
        questionout.println("题目数量:" + i);


        for(m=1; m<=i; m++){
            t[m] = n.CreateFormula(a);
            questionout.println(m + "、" + t[m] + "=");
            b = Formula.calculateFormulaString(t[m]);
            answerout.println(m + "、" + b.output());
        }
        System.out.println("成功生成题目与答案");

    }
}

五、测试运行

生成一万道题目


 

六、项目小结

第一次进行结对编程,和舍友分工合作,他负责核心算法(Formula类)的编写,我负责Create类和Output类的编写,有效提高了工作效率。

 

posted on 2018-09-29 23:30  JJYdesu  阅读(174)  评论(0)    收藏  举报