结对项目——贾基东&迪力木热提·开依散尔

发布时间 2023-09-28 21:18:50作者: 留白1
这个作业属于哪个课程 计科21级12班
这个作业要求在哪里 结对项目
这个作业的目标 实现一个自动生成小学四则运算题目的命令行程序

团队成员信息

姓名 学号
贾基东 3121004864
迪力木热提·开依散尔 3121004859

gitee:https://gitee.com/jiajidong/3121004864/tree/master/

1.PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 80 90
Estimate 估计这个任务需要多少时间 1690 1950
Development 开发 110 130
Analysis 需求分析 (包括学习新技术) 300 400
Design Spec 生成设计文档 70 70
Design Review 设计复审 30 20
Coding Standard 代码规范 (为目前的开发制定合适的规范) 30 30
Design 具体设计 400 500
Coding 具体编码 300 400
Test 测试(自我测试,修改代码,提交修改) 120 110
Reporting 报告 90 80
Test Report 测试报告 40 30
Size Measurement 计算工作量 50 50
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 70 40
合计 1690 1950

2.效能分析

3.设计实现

3.1编写的类

3.1.1 CheckWork类

主要实现对自动生成题目的回答进行批改,得出答题情况,即对两个文件逐行读取,对比
若是未作答,会报错

类方法接口:
public static void check(String AT,String aT,String GT)

3.1.2 FinishWork类

主要实现把对应四则运算的式子进行变换,从中缀变为后缀,并得出结果
类方法接口:
public FinishWork(ArrayList<String> list)
public ArrayList<String> parseToSuffixExpression(ArrayList<String> list)
public boolean istype(String type)
public boolean isnum(String num)
public static int priority(String op)
public Opertion cal(ArrayList<String> list)
主要代码:

public class FinishWork {
 	ArrayList<String> list = new ArrayList<>();
 	public FinishWork(ArrayList<String> list) {
 		this.list = list;
 	}
 	public ArrayList<String> parseToSuffixExpression(ArrayList<String> list){
 		Stack<String> opStack = new Stack<>();
 		ArrayList<String> suffixList = new ArrayList<>();
 		for(String item : list) {
 			if(this.istype(item)) {
 				if(opStack.isEmpty()||"(".equals(opStack.peek())||this.priority(item)>this.priority(opStack.peek())) {
 					opStack.push(item);
 				}else {
 					while(!opStack.empty()&&!"(".equals(opStack.peek())) {
 						if(this.priority(item) <= this.priority(opStack.peek())){
                            suffixList.add(opStack.pop());
                        }
 					}
 					opStack.push(item);
 				}
 			}else if(this.isnum(item)) {
 				suffixList.add(item);
 			}else if("(".equals(item)) {
 				opStack.push(item);
 			}
 			 else if(")".equals(item)) {
 				while(!opStack.empty()) {
 					if("(".equals(opStack.peek())) {
 						opStack.pop();
 						break;
 					}else {
 						suffixList.add(opStack.pop());
 					}
 				}
 			}else {throw new RuntimeException("有非法字符!");} 
 		}
 		while (!opStack.isEmpty()){
            suffixList.add(opStack.pop());
        }
		return suffixList;
 	}
 	public boolean istype(String type) {
 		return type.equals("+")||type.equals("-")||type.equals("*")||type.equals("÷");
 	}
 	public boolean isnum(String num) {             //
 		if(num.charAt(0)>='0'&&num.charAt(0)<='9')
 		return true;
 		else return false;
 	}
 	public static int priority(String op){
        if(op.equals("*") || op.equals("÷")){
            return 1;
        }else if(op.equals("+") || op.equals("-")){
            return 0;
        }
        return -1;
    }
 	public Opertion cal(ArrayList<String> list) {                 //
 		Opertion n = null;
 		Stack<Opertion> stack = new Stack<>();
 		for(int i = 0;i<list.size();i++) {
 			String item = list.get(i);
 			if(isnum(item)) {                       //
 				stack.push(n.toOpertion(item));
 			}else {
 				Opertion num1 = stack.pop();
 				Opertion num0 = stack.pop();
 				Opertion res;
 				if(item.equals("+")) res = num0.add(num1);
 				else if(item.equals("-")) res = num0.sub(num1);
 				else if(item.equals("*")) res = num0.mul(num1);
 				else if(item.equals("÷")) res = num0.div(num1);
 				else throw new RuntimeException("运算符错误!");
 	 			stack.push(res);
 			}
 		}
 		
 		return stack.pop();
 	}

}

3.1.3 main类

主类,完成对操作行中r(生成算式数量)与n(算式数最大值)的输入,以及对MakeWork类中的Make方法的运用

3.1.4 MakeWork类

主要完成四则运算式子的生成,并运用其他类方法,完成对该式的运算以及写入文件中

主要类方法:
public void Make()
public void make(int mt)
主要代码:

 public void Make() {
    	 for(int i = 0;i < n;i++) {
    		 this.make(i+1);
    	 }
     }public void make(int mt) {                 //生成算式
     	Random r = new Random();
     	PutWork f = new PutWork();
     	int num = r.nextInt(2)+3;
     	int t = r.nextInt(5);
     	int issub = 0;
     	Opertion next;
     	Opertion temp = null;
     	if(t>=num-1) t = -2;
     	ArrayList<String> list = new ArrayList<>();
     	for(int i = 0;i<num;i++) {
     	if(i==t) list.add("(");
     	next = random();
     	if(i==t&&issub==1) {           //-(
     		Opertion num0 = temp.toOpertion(list.get(list.size()-3));
     		while(issub==1) {
     			if(num0.mycompare(next))
     			issub = 0;
     			else next = random();
     		}
     		
     	}else if(i==t+1&&issub==1) {     //)-
     		Opertion num0 = temp.toOpertion(list.get(list.size()-3));
     		while(issub==1) {
     			if(num0.mycompare(next))
     			issub = 0;
     			else next = random();
     		}
     	}else if(issub==1) {            //-
     		Opertion num0 = temp.toOpertion(list.get(list.size()-2));
     		while(issub==1) {
     			if(num0.mycompare(next))
     			issub = 0;
     			else next = random();
     		}
     	}
     	list.add(next.toString());
     	//     	list.add(Integer.toString(random());                整数
     	if(i==t+1) list.add(")");
     	if(i!=num-1) list.add(Character.toString(this.type()));
     	if(list.get(list.size()-1).equals("-")) {issub = 1;if(i<t) {t++;if(t>=num-1) t = -2;}}
     	}
     	System.out.println(list);
     	FinishWork p = new FinishWork(list);
     	//System.out.println(p.parseToSuffixExpression(list));
     	System.out.println(p.cal(p.parseToSuffixExpression(list)));
     	f.putwork("Exercises.txt", "Answers.txt", String.join("", list), mt, p.cal(p.parseToSuffixExpression(list)));
     }
     public void putList(ArrayList<String> list,String s) {
    	 list.add(s);
     }

3.1.5 Opertion类

主要实现定一个新的数据类,该类为分式,所有数字均为该类,整数则在分子为0,并在类方法中完成两个该数据类的四则运算
主要代码:

public class Opertion {
      int mol;        //分子
      int den;        //分母
      int num;        //真数
      public Opertion(int mol,int den) {
    	  this.mol = mol;
    	  this.den = den;
    	  this.num = this.cancel();
      }
      public int cancel() {
    	  int tnum = 0;
    	  tnum = this.mol / this.den;
    	  this.mol = this.mol % this.den;
    	  this.yue();
    	  return tnum;
      }
      public void yue() {
    	  if(this.mol==0) return;
    	  int yue = this.gcd(this.mol,this.den);
    	  this.mol = this.mol / yue;
    	  this.den = this.den / yue;
      }
      public static int gcd(int mol,int den) {
    	while(mol!=den) {
    		if(mol>den) mol-=den;
    		else den-=mol;
    	}
    	return mol;
      }
      public String toString() {
    	  StringBuilder sb = new StringBuilder(""); 
    	  if(num!=0) {sb.append(Integer.toString(num));
    	  if(mol!= 0)sb.append("'");}
    	  if(mol!=0) {sb.append(Integer.toString(mol));
    	  sb.append("/");
    	  sb.append(Integer.toString(den));}
    	  if(num==0&&mol==0) sb.append("0");
    	  String str = sb.toString();
    	  return str;
      }
      public static  Opertion toOpertion(String str) {
    	  int num = 0;
    	  int mol = 0;
    	  int den = 1;
          if(str.length()==1) num = str.charAt(0)-'0';
          else if(str.length()==3) {
        	  mol = str.charAt(0)-'0';
        	  den = str.charAt(2)-'0';
          }
          else {
        	  num = str.charAt(0)-'0';
        	  mol = str.charAt(2)-'0';
        	  den = str.charAt(4)-'0';
          }
          Opertion t = new Opertion(num*den+mol,den);
    	  return t;
      }
      public boolean mycompare(Opertion num1) {             //比较,当其大于等于num1时,返回true
    	  if(this.num>num1.num) return true;
    	  else if(this.num==num1.num) {
    		  if(this.mol*num1.den>=num1.mol*this.den)
    		  return true;
    		  else return false;
    	  }else return false;
      }
      public Opertion add(Opertion num1) {     //加
    	  int num = 0;
    	  int mol = 0;
    	  int den = 1;
    	  num = this.num+num1.num;
    	  mol = this.mol*num1.den+this.den*num1.mol;
    	  den = this.den*num1.den;
    	  Opertion t = new Opertion(num*den+mol,den);
    	  return t;
      }
      public Opertion sub(Opertion num1) {       //减
    	  int mol = 0;
    	  int den = 1;
    	  mol = (this.mol+this.den*this.num)*num1.den-this.den*(num1.mol+num1.den*num1.num);
    	  den = this.den*num1.den;
    	  Opertion t = new Opertion(mol,den);
    	  return t;
      }
      public Opertion mul(Opertion num1) {       //乘
    	  int mol = 0;
    	  int den = 1;
          mol = (this.num*this.den+this.mol)*(num1.num*num1.den+num1.mol);
          den = this.den*num1.den;
    	  Opertion t = new Opertion(mol,den);
    	  return t;
      }
      public Opertion div(Opertion num1) {           //除
    	  int mol = 0;
    	  int den = 1;
    	  mol = (this.num*this.den+this.mol)*num1.den;
    	  den = (num1.num*num1.den+num1.mol)*this.den;
    	  Opertion t = new Opertion(mol,den);
    	  return t;
      }
      /*  public static void main(String[] args) {
        Opertion num = new Opertion(30,20);
        System.out.println(num.toString());
        Opertion num1 = toOpertion("1'1/2");
        System.out.println(num1.toString());
        Opertion add = num.add(num1);
        System.out.println(add.toString());
        Opertion sub = num.sub(num1);
        System.out.println(sub.toString());
        Opertion mul = num.mul(num1);
        System.out.println(mul.toString());
        Opertion div = num.div(num1);
        System.out.println(div.toString());
        System.out.println(num.mycompare(num1));
  	}  */
}

3.1.5 PutWork类

该类主要实现对生成的四则运算式子放入文件之中
类方法:
public void putwork(String WT,String AT,String work,int mt,Opertion Answer)

3.2 大致流程图

4. 总结

本次结对作业总体来说基本完成,在本次结对作业中,不仅在代码方面有所精进,更是切身体会到团队协作,虽在在刚开始合作可以比较困难,代码开发效率不如单个人,经常出现接口不一致,以及在编码的过程出现各种问题,不过在互相磨合以及相互督促改正过程中,完成了本次结对作业。