github项目传送门:https://github.com/yaokangyou/arithmetic

项目要求

  • 功能列表
  1. [完成] 使用 -n 参数控制生成题目的个数
  2. [完成] 使用 -r 参数控制题目中数值的范围, 。该参数可以设置为1或其他自然数
  3. [完成] 生成的题目中计算过程不能产生负数
  4. [完成] 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数
  5. [完成] 程序一次运行生成的题目不能重复,生成的题目存入执行程序的当前目录下的Exercises.txt文件
  6. [完成] 每道题目中出现的运算符个数不超过3个
  7. [完成] 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件
  8. [完成] 程序应能支持一万道题目的生成。
  9. [完成] 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计

PSP开发耗时

PSP2.1

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 30  60

· Estimate

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

 30  60

Development

开发

 1000  2140

· Analysis

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

 100  180

· Design Spec

· 生成设计文档

 60  100

· Design Review

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

 30  30

· Coding Standard

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

 30  30

· Design

· 具体设计

 120  150

· Coding

· 具体编码

 600  1500

· Code Review

· 代码复审

 50  60

· Test

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

 150  60

Reporting

报告

 80  80

· Test Report

· 测试报告

 30  40

· Size Measurement

· 计算工作量

 20  10

· Postmortem & Process Improvement Plan

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

 30  20

合计

   1110  2280

设计

表达式:

我们平时运用和看见的表达式一般都是中缀表达式,也就是 1 + 1 + 2,这次我们为了实现表达式判重和运算,我们在表达式操作中统一把中缀表达式转为逆波兰表达式,也就是我们通常所说的后缀表达式 1 1 + 2 +,后缀表达式不像中缀表示法,还有各种优先级啊,还有小括号之类的,逻辑特别麻烦,而逆波兰表示法比较简洁,完全不用考虑优先级,也没用小括号,中括号还有大括号搅局。

逆波兰表达式:

负数:

在用逆波兰表达式计算时,我们在manager类中会对每次的计算过程都会调用symbol类的自定义运算方法,每一步运算出来负数就会返回-1给manager类,把每一步的计算结果和最终结果用字符串数组存起来,遍历筛选。

分数,整数的表示​​​​​​​:

思路是把全部的数,包括整数也当作分数计算,然后在输出的时候做处理。

判断是否重复​​​​​​​:

思路是把成功输出的式子用一个hashMap存起来,key为表达式,value为字符串数组,字符串数组是在逆波兰表达式计算时记录的最终答案和每一步的运算结果。

当hashMap有重复的key时候,直接返回false,当遍历寻找hashMap中有相同的字符串数组,用list记录,当list的长度大于零,对key用sort排序对比,相同就重复,不同就true。例如 3+(2+1)+4  ,1 + 2 + 4 + 3 ,这两个不重复,但是数字符号答案相同,但第二次运算结果不同,所以不重复。

用户使用说明

举例:

-n   [数值]     使用 -n 参数控制生成题目的个数。

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

-e   <exercisefile>.txt -a <answerfile>.txt  对给定的题目文件和答案文件,判定答案中的对错并进行数量统计 。

代码

项目目录:

主函数:(启动程序)main.java

public static void main(String[] args) throws IOException{
System.out.println("**** -n [数值] 使用 -n 参数控制生成题目的个数");
System.out.println("**** -e <exercisefile>.txt -a <answerfile>.txt 对给定的题目文件和答案文件,判定答案中的对错并进行数量统计");
System.out.print("请输入命令:");
Scanner s = new Scanner(System.in);
String m =s.nextLine();
String arr[]=m.split("\\s");
switch (arr[0]){
case "-n":
System.out.println("**** -r [数值] 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围");
System.out.print("请输入命令:");
Scanner scope = new Scanner(System.in);
String numScope = scope.nextLine();
String Scope[]=numScope.split("\\s");
manager Manager=new manager(new Integer(arr[1]).intValue(), new Integer(Scope[1]).intValue());
Manager.produceproblems(new Integer(arr[1]).intValue());
break;
case "-e":
answerJudge.Judge(arr[1], arr[3]);
break;
default:
System.out.println("输入的命令有误!");main(args);break;
} }

生成表达式:

产生整数

String produceinteger(int range) {
String integer = "";
Random seed=new Random();
int result=seed.nextInt(range)+1; //控制随机数范围为1-range
integer=new Integer(result).toString();
return integer;
}

产生分数

String producefraction(int range) {
String fraction="";
Random seed=new Random();
int numerator=seed.nextInt(range)+1;//分子
int denominator=seed.nextInt(range)+1;//分母
if(numerator==denominator) {
fraction="1";
return fraction;
}
while((range*denominator)<numerator) {
numerator=seed.nextInt(range)+1;
denominator=seed.nextInt(range)+1;
} int mixernumber=0;//带分数的整数部分
while(numerator>denominator) {
numerator-=denominator;
mixernumber++;
} fraction=(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString()); if(mixernumber>0) {
fraction=(new Integer(mixernumber).toString())+"`"+(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString());
if(numerator==denominator) {
fraction=new Integer(mixernumber).toString();
}
}
return fraction;
} 

产生数

String producedigit() {
String digital="";
Random seed=new Random();
int random=seed.nextInt(2);
if(random==0)digital=produceinteger(this.range);
else digital=producefraction(this.range);
return digital;
}

通分和约分

//约分
String reductfrac(String fraction){
String result="";
String []fracs;
fracs=fraction.split("/");
int numerator=new Integer(fracs[0]).intValue();
if(numerator==0) {
result="0";
return result;
}
int denominator=new Integer(fracs[1]).intValue();
int temp1,temp2;
if(denominator>numerator) {
temp1=denominator;
temp2=numerator;
}
else {
temp1=numerator;
temp2=denominator;
}
int res=temp1%temp2;
while(res!=0) {
temp1=temp2;
temp2=res;
res=temp1%temp2;
}
numerator/=temp2;
denominator/=temp2;
result=(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString());
return result;
} //通分
String sharing(String para1,String para2) {
String result="";
String []para1s;
String []para2s;
para1s=para1.split("/");
para2s=para2.split("/");
int numerator=new Integer(para1s[0]).intValue();
int denominator=new Integer(para1s[1]).intValue();
int denominator2=new Integer(para2s[1]).intValue();
int temp1=new Integer(para1s[1]).intValue();
int temp2=new Integer(para2s[1]).intValue();
int res;
if(temp1<temp2) {
res=temp1;
temp1=temp2;
temp2=res;
}
res=temp1%temp2;
while(res!=0) {
temp1=temp2;
temp2=res;
res=temp1%temp2;
}
denominator=denominator*denominator2/temp2;
numerator=numerator*denominator2/temp2;
result=(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString());
return result;
}

数值互转

//整数,带分数转分数
String changetofraction(String para1) {
String result="";
if(para1.indexOf("/")<0) {
if(para1=="0") {
result="0";
}
else {
result=para1+"/"+"1";
}
}
else if(para1.indexOf("`")<0) {
result=para1;
}
else {
String []temp1=para1.split("`");
String times=temp1[0];
String []temp2=temp1[1].split("/");
int numerator=(new Integer(temp2[1]).intValue())*(new Integer(times).intValue())+(new Integer(temp2[0]).intValue());
int denominator=new Integer(temp2[1]).intValue();
result=(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString());
}
return result;
} //分数转整数
String changetointeger(String para1) {
String result="";
result=para1.split("/")[0];
return result;
} //分数转带分数
String changrtomixfrac(String para1) {
String result="";
String []para1s;
para1s=para1.split("/");
int numerator=new Integer(para1s[0]).intValue();
int denominator=new Integer(para1s[1]).intValue();
int mixernumber=0;//带分数的整数部分
while(numerator>denominator) {
numerator-=denominator;
mixernumber++;
}
result=(new Integer(mixernumber).toString())+"`"+(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString());
return result;
}

自定义的计算函数:

package main.controller;
import java.io.*;
import java.lang.*;
import java.util.Random; public class symbol {
String operators; symbol(){
this.operators="+-*/";
} String produceoperator() {
String operator="";
Random seed=new Random();
int random=seed.nextInt(4);
operator=new Character(this.operators.charAt(random)).toString();
return operator;
} String add(String para1,String para2) {
String result="";
String []para1s;
String []para2s;
para1s=para1.split("/");
para2s=para2.split("/");
int numerator=(new Integer(para1s[0]).intValue())+(new Integer(para2s[0]).intValue());
int denominator=(new Integer(para1s[1]).intValue());
int mixernumber=0;//带分数的整数部分
while(numerator>denominator) {
numerator-=denominator;
mixernumber++;
}
result=(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString());
result=new digit().reductfrac(result);
if(mixernumber>0) {
result=(new Integer(mixernumber).toString())+"`"+(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString());
} return result;
} String subtract(String para1,String para2) {
String result="";
String []para1s;
String []para2s;
para1s=para1.split("/");
para2s=para2.split("/");
int numerator=(new Integer(para1s[0]).intValue())-(new Integer(para2s[0]).intValue());
if(numerator<0) {
result="-1";
return result;
}
if(numerator==0) {
result="0";
return result;
}
int denominator=(new Integer(para1s[1]).intValue());
int mixernumber=0;//带分数的整数部分
while(numerator>denominator) {
numerator-=denominator;
mixernumber++;
}
result=(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString());
result=new digit().reductfrac(result);
if(mixernumber>0) {
result=(new Integer(mixernumber).toString())+"`"+(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString());
}
return result;
} String multiply(String para1,String para2) {
String result="";
String []para1s;
String []para2s;
para1s=para1.split("/");
para2s=para2.split("/");
int numerator=(new Integer(para1s[0]).intValue())*(new Integer(para2s[0]).intValue());
int denominator=(new Integer(para1s[1]).intValue())*(new Integer(para2s[1]).intValue());
int mixernumber=0;//带分数的整数部分
while(numerator>denominator) {
numerator-=denominator;
mixernumber++;
} result=(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString());
result=new digit().reductfrac(result);
if(mixernumber>0) {
result=(new Integer(mixernumber).toString())+"`"+(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString());
}
return result;
} String divide(String para1,String para2) {
String result="";
String []para1s;
String []para2s;
para1s=para1.split("/");
para2s=para2.split("/");
String temp="";
if(para2=="0") {
result="-2";
return result;
}
int numerator,denominator;
numerator=(new Integer(para1s[0]).intValue())*(new Integer(para2s[1]).intValue());
denominator=(new Integer(para1s[1]).intValue())*(new Integer(para2s[0]).intValue());
result=(new Integer(numerator).toString())+"/"+(new Integer(denominator).toString());
result=new digit().reductfrac(result);
return result;
} }

逆波兰表达式生成:

  String changetopostfix(String problem) {
String result="";
Stack<String> digit=new Stack();
Stack<String> symbol=new Stack();
String[] items=problem.split(" ");
int stackpri=0;
int enterpri=0;
int kuopri=0;
int first=0;
String temp="";
String temp2=""; for(int i=0;i<items.length;i++) {
if((items[i].compareTo("(")==0)||(items[i].compareTo(")")==0)||(items[i].compareTo("+")==0)||(items[i].compareTo("-")==0)||(items[i].compareTo("*")==0)||(items[i].compareTo("/")==0)||(items[i].compareTo("=")==0)) {
switch(items[i].charAt(0)) {
case '+':enterpri=1;break;
case '-':enterpri=1;break;
case '*':enterpri=2;break;
case '/':enterpri=2;break;
case '(':enterpri=3;break;
case ')':enterpri=4;break;
case '=':enterpri=0;break;
}
if(symbol.isEmpty()==true) {
symbol.add(items[i]);
stackpri=enterpri;
}
else {
if(enterpri>stackpri) {
if(enterpri==4) {
temp=digit.pop();
temp2+=digit.pop()+" "+temp+" "+symbol.pop();
digit.add(temp2);
temp2="";
if(first==0)first=1;
symbol.pop();
stackpri=kuopri;
}
else if(enterpri==3) {
symbol.add(items[i]);
kuopri=stackpri;
stackpri=0;
}
else {
symbol.add(items[i]);
stackpri=enterpri;
}
}
else {
if(first==0) {
temp=digit.pop();
temp2+=digit.pop()+" "+temp+" "+symbol.pop();
digit.add(temp2);
first=1;
temp2="";
}
else {
temp=digit.pop();
temp2+=digit.pop()+" "+temp+" "+symbol.pop();
digit.add(temp2);
temp2="";
}
symbol.add(items[i]);
}
}
}
else {
digit.add(items[i]);
}
}
if(symbol.isEmpty()==false) {
symbol.pop();
while(symbol.isEmpty()==false) {
temp=digit.pop();
result+=digit.pop()+" "+temp+" "+symbol.pop()+" ";
temp="";
}
if(digit.isEmpty()==false) {
result+=digit.pop();
}
}
return result;
}

逆波兰表达式计算

String []calculator(String result) {
String [] arr = {"", "", "", ""};
String [] s = result.split(" ");
int num = 1;
List<String> problemResult = new ArrayList<>(); for (int i = 0; i < s.length; i++) {
int size = problemResult.size();
switch (s[i]) {
case "+": String a=calculatorChildren(problemResult.remove(size-2), problemResult.remove(size-2), "+");
problemResult.add(a);arr[num++]=a;break;
case "-": String b=calculatorChildren(problemResult.remove(size-2), problemResult.remove(size-2), "-");
problemResult.add(b);arr[num++]=b;break;
case "*": String c=calculatorChildren(problemResult.remove(size-2), problemResult.remove(size-2), "*");
problemResult.add(c);arr[num++]=c;break;
case "/": String d=calculatorChildren(problemResult.remove(size-2), problemResult.remove(size-2), "/");
problemResult.add(d);arr[num++]=d;break;
default: problemResult.add(s[i]);break;
}
}
arr[0] = problemResult.get(0);
answerPrint = arr[0];
return arr;
} String calculatorChildren(String para1,String para2,String oper) {
String answer="";
String temp1="";
String temp2="";
String answerstr="";
temp1=new digit().changetofraction(para1);
temp2=new digit().changetofraction(para2);
temp1=new digit().sharing(temp1, temp2);
temp2=new digit().sharing(temp2, temp1);
switch(oper.charAt(0)) {
case '+':answerstr=new symbol().add(temp1, temp2);break;
case '-':answerstr=new symbol().subtract(temp1, temp2);break;
case '*':answerstr=new symbol().multiply(temp1, temp2);break;
case '/':answerstr=new symbol().divide(temp1, temp2);break;
}
if(answerstr.equals("-1")) {
answer="-1";
return answer;
}
answerstr=new digit().changetofraction(answerstr);
answerstr=new digit().reductfrac(answerstr); String temp3=answerstr;
String[]temp4=temp3.split("/");
if(temp4.length==2) {
if(new Integer(temp4[0]).intValue()<new Integer(temp4[1]).intValue()) {
answer=answerstr;
}
else if((new Integer(temp4[1]).intValue())==1) {
answer=new digit().changetointeger(answerstr);
}
else {
answer=new digit().changrtomixfrac(answerstr);
}
}
else answer="1";
return answer;
}

表达式判断重复:

  Boolean judgeproblem(String problem) {
if(problems.containsKey(problem)) {
return false;
}
String postfix=changetopostfix(problem);
String []result=calculator(postfix);
String firstresult = result[1];
String secondresult="";
if(result.length>3) { secondresult=result[2];}
String finalresult = result[0]; for (int i = 0; i < result.length; i++) {
if(result[i].equals("-1")||result[i].equals("-2")) return false;
} List<String> keyList = new ArrayList();
char[] postfixChar = postfix.toCharArray();
Arrays.sort(postfixChar);
String sortPostfixChar = String.valueOf(postfixChar);
for(String getKey: problems.keySet()){
if(result.length>3) {
if(problems.get(getKey)[0].equals(finalresult)&&problems.get(getKey)[1].equals(firstresult)&&problems.get(getKey)[2].equals(secondresult)){
keyList.add(getKey);
}
}
else {
if(problems.get(getKey)[0].equals(finalresult)&&problems.get(getKey)[1].equals(firstresult)){
keyList.add(getKey);
}
}
} if (keyList.size()>0) {
for(int j = 0; j < keyList.size();j++) {
char[] strChar = keyList.get(j).toCharArray();
Arrays.sort(strChar);
String sortstrChar = String.valueOf(strChar);
if (sortstrChar.equals(sortPostfixChar)) {
return false;
}else {
continue;
}
}
problems.put(postfix, result);
return true;
}
problems.put(postfix, result);
return true;
}

输出表达式到Exercises.txt和输出答案到Answers.txt:

File exercises = new File("Exercises.txt");
File answers = new File("Answers.txt"); FileOutputStream exercisesOutput = new FileOutputStream(exercises);
PrintStream exercisesPrintStream = new PrintStream(exercisesOutput); FileOutputStream answersOutput = new FileOutputStream(answers);
PrintStream answersPrintStream = new PrintStream(answersOutput); void save(String problem, String answer, int count, PrintStream exercisesPrintStream, PrintStream answersPrintStream) throws FileNotFoundException, IOException {
String[] problems = new String[2];
problems[0] = problem;
problems[1] = answer;
outputFile(count, problems, exercisesPrintStream, answersPrintStream);
} public void outputFile(int i, String problems[], PrintStream... var){
try {
var[0].println(i + ". " + problems[0]);
var[1].println(i + ". " + problems[1]);
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("程序内部出错了");
}
}

对给定的题目文件和答案文件,判定答案中的对错并进行数量统计:

public class answerJudge {
public static void Judge(String exercisePath, String answersPath) throws IOException {
List<String> exerciseAnswers = exerciseFileRecording(exercisePath);
List<String> answers = answerRecording(answersPath); List<String> correct = new ArrayList<>();
List<String> wrong = new ArrayList<>();
int SerialNumber = ;
int MIN = Math.min(exerciseAnswers.size(), answers.size()); for (int i = ; i < MIN; i++){
if (exerciseAnswers.get(i).equals(answers.get(i))){
correct.add(String.valueOf(SerialNumber++));
}else {
wrong.add(String.valueOf(SerialNumber++));
}
} File grade = new File("Grade.txt");
if (grade.exists()){
grade.delete();
}
if (grade.createNewFile()){
FileOutputStream gradeOutput = new FileOutputStream(grade);
PrintStream gradePrintStream = new PrintStream(gradeOutput);
String corrects = String.join(",", correct);
gradePrintStream.println("Correct:" + correct.size() +
" (" + corrects + ")");
String wrongs = String.join(",", wrong);
gradePrintStream.println("Wrong:" + wrong.size() +
" (" + wrongs + ")");
}
System.out.println("判定完成!记录在Grade.txt。");
} public static List<String> exerciseFileRecording(String path) throws IOException {
String exerciseAnswer = "";
BufferedReader exerciseRecording = new BufferedReader(new FileReader(path));
List<String> exerciseAnswers = new ArrayList<>();
while ((exerciseAnswer = exerciseRecording.readLine()) != null){
String[] split = exerciseAnswer.split("=");
if (split.length >= ){
exerciseAnswers.add(split[]);
}else {
exerciseAnswers.add(" ");
}
}
return exerciseAnswers;
} public static List<String> answerRecording(String path) throws IOException {
String answer = "";
BufferedReader answerRecording = new BufferedReader(new FileReader(path));
List<String> answers = new ArrayList<>();
while ((answer = answerRecording.readLine()) != null){
String[] split = answer.split(" ");
answers.add(split[]);
}
return answers;
}
}

测试运行

表达式的输出

随机输出10条5范围以内的表达式和答案

随机输出10000条10范围以内的表达式和答案:

由于太多,给个连接打开

点击我查看10000条表达式

点击查看答案

结果的对比

 故意把2,7,10的答案填错

代码覆盖率

进行代码覆盖率测试

代码覆盖率:94.4%

总结

与黎扬乐同学一起实现该次题目,他主要负责代码框架的构思和表达式的计算和生成,我主要负责判重,判负以及文件输出和结果判定。总体来说,在这个作业里面,黎扬乐同学主要负责的是逻辑计算,我主要负责逻辑判断和博客。结对编程有个好处就是能让我们能讨论代码的思路和一起debug。在完成这次作业之前,我们两个可以在一起先把整个作业的流程和代码框架设计出来,把整体的代码知识点全部统计出来,两个人的想法可以在一起碰撞,这样可以在代码实现的过程中大大减少做弯路的时间,包括判重和采用逆波兰表达式等等。这一次,我们两个在合作的过程也出现了一些不足之处,最主要的问题是我们两个这次为了方便没有采用gitlab的协同方式,导致两个的代码在实现的过程产生了很多不必要的错误和bug。相对而言,黎扬乐同学的在逻辑代码算法的能力比较扎实,也多得他把后缀表达式的转化这一块完成,这次作业才可以在短时间完成,这次合作中,也让我认识到自己在数据结构这一块还是很薄弱,以前那种前端开发是不太需要数据结构的想法是错误的,今后自己一定会加强数据结构的学习。

四则运算 Java 姚康友,黎扬乐的更多相关文章

  1. 四则运算 Java 杨辉鹏,郑冠华

    四则运算 Java 杨辉鹏,郑冠华 GitHub链接:https://github.com/yanghuipeng/arithmetic 项目相关要求 使用 -n 参数控制生成题目的个数,例如 -n ...

  2. 四则运算Java语言实验设计过程1

    题目要求: 像二柱子那样,花二十分钟写一个能自动生成三十道小学四则运算题目的 “软件”.要求:除了整数以外,还要支持真分数的四则运算(需要验证结果的正确性).题目避免重复.可定制出题的数量. 设计思路 ...

  3. 四则运算(Java)--温铭淇,付夏阳

    GitHub项目地址: https://github.com/fxyJAVA/Calculation 四则运算项目要求: 程序处理用户需求的模式为: Myapp.exe -n num -r size ...

  4. 四则运算 Java 实现 刘丰璨,王翠鸾

    四则运算 GitHub仓库 功能实现 [x] 使用 -n 参数控制生成题目的个数,并且根据解空间限制用户设定的范围(如 range == 2 时,用户却要求生成 10000 道题目,这明显不合理) [ ...

  5. 四则运算 Java (于泽浩,袁浩越)

    GitHub 地址 一. 项目要求 题目 实现一个自动生成小学四则运算题目的命令行程序. 需求(全部完成) 使用 -n 参数控制生成题目的个数 Myapp.exe -n 10 使用 -r 参数控制题目 ...

  6. 结对编程四则运算--JAVA实现(徐静、林文敏)

    Github项目地址 项目相关要求 -n 参数控制生成题目的个数 (√) Myapp.exe -n 10 // 将生成10个题目 -r 参数控制题目中数值(自然数.真分数和真分数分母)的范围 (√) ...

  7. 小学生四则运算JAVA

    点我,github地址 组员:黄浩格,何坤 一.项目说明 1题目:实现一个自动生成小学四则运算题目的命令行程序. 2说明: 自然数:0, 1, 2, -. • 真分数:1/2, 1/3, 2/3, 1 ...

  8. 算法笔记_156:算法提高 6-17复数四则运算(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 设计复数库,实现基本的复数加减乘除运算. 输入时只需分别键入实部和虚部,以空格分割,两个复数之间用运算符分隔:输出时按a+bi的格式在屏幕上打印结果 ...

  9. 四则运算(Java) 陈志海 邓宇

    目录 Github项目地址 PSP表格 功能要求 题目 功能(已全部实现) 效能分析 设计实现过程 数值生成 算式生成 问题集生成 设计实现过程 代码说明 测试运行 代码覆盖率 项目小结 Github ...

随机推荐

  1. python --第三方登录--微博

    理解第三方登录的流程: 用户向本地应用商城发起请求,我要用微博进行登录 我们的商城凑一个url让用户跳转到第三方应用的url(微博的登录页面) 用户在该界面点击输入用户名密码之后,点击授权. 微博有个 ...

  2. [每天解决一问题系列 - 0009] File System Redirector

    问题描述: 在64位操作系统下,知道Wow64是干什么的,但一直不知道是怎么工作的 相关解释: https://msdn.microsoft.com/en-us/library/windows/des ...

  3. python列表常用方法

    list是一个类,用中括号括上,逗号分隔,元素可以是数字,字符,字符串,也可以是嵌套列表,布尔类型. 1.通过索引取值 li=[1,12,9,'age',['wangtianning',[19,'10 ...

  4. TCP/IP 笔记 - 防火墙和网络地址转换

    防火墙是位于内部网和外部网之间的屏障,是系统的第一套防线,作用是防止非法用户的进入. 网络地址转换是一种IP数据包通过路由器或防火墙时通过重写来源IP地址或目的地址的技术,可以用来隐藏或保护内部网络, ...

  5. Linux 学习手记(2):Linux文件系统的基本结构

    Linux 文件系统概况 Linux文件系统为一个倒置的树状结构,所有文件或文件夹均包含在一个根目录“/”中.如图所示(每个目录的作用可以参考:Linux目录结构说明): Linux系统严格区分大小写 ...

  6. filter listener interceptor的区别

    转自: http://www.cnblogs.com/shangxiaofei/p/5328377.html https://www.cnblogs.com/jinb/p/6915351.html 一 ...

  7. 新手易犯的典型缺陷--C#

    这段时间花了点时间整理了几个新手易犯的典型缺陷(专门针对C#的),但是个人的力量毕竟有限缺陷的覆盖面比较窄,有些缺陷的描述也不够准确,这里先贴出来看看能不能集思广益,收集整理出更多的典型缺陷.目标就是 ...

  8. DataAnnotations - InverseProperty Attribute:

    DataAnnotations - InverseProperty Attribute: We have seen in the Code-First Convention section that ...

  9. JavaWeb学习 (二十六)————监听器(Listener)学习(二)

    一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信 ...

  10. [译]WebAPI下的如何实现参数绑定

    本文将概述在WebAPI方式下将如何将参数绑定到一个action方法,包括参数是如何被读取,一系列规则决定特定环境采用的那种绑定方式,文章最后将给出一些实际的例子. Parameter binding ...