java 四则运算_java实现小学生四则运算

结对伙伴:叶文涛

项目要求:

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

使用 -n 参数控制生成题目的个数(完成)

使用 -r 参数控制题目中数值的范围, 。该参数可以设置为1或其他自然数。(完成)

生成的题目中计算过程不能产生负数(完成)

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

程序一次运行生成的题目不能重复,生成的题目存入执行程序的当前目录下的Exercises.txt文件(完成)

每道题目中出现的运算符个数不超过3个(完成)

在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件(完成)

程序应能支持一万道题目的生成。(完成)

程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计。(完成)

设计:

分为两个部分,第一是生成题目,生成表达式及答案后写入当前目录下的文件,第二是判断答案是否正确,读取文件后判断,再将结果写入当前目录下的文件。

743fa3b48e9b8257b00cdf5cd661b791.png

代码

主函数

public static voidmain(String[] args){

System.out.println("请选择功能:");

System.out.println(" 1. 四则运算生成器");

System.out.println(" 2. 答案对比");

System.out.print("请输入你的选择[1/2]:");int choose = newScanner(System.in).nextInt();switch(choose){case 1:

ProducerController producerController= newProducerController();

producerController.ConstructProblem();break;case 2:

JudgeAnswerController judgeAnswerController= newJudgeAnswerController();

judgeAnswerController.start();break;default:

System.out.println("输入不正确,请输入1或2");main(args);break;

}

}

整数生成器与真分数生成器函数

public String[] createProblem(intrange){

Random random= newRandom();int operatorCount = 1 + random.nextInt(3); //随机操作符的个数(1-3个)

int operand[] = new int[operatorCount + 1]; //操作数个数

int[] operatorIndex = index(operatorCount, 4, random);for(int i = 0; i < operatorCount + 1; i++){

operand[i]=random.nextInt(range);

}

String formula=stitchingFormula(operatorCount, operand, operatorIndex);//计算结果

Calculator calculator = newCalculator();int res =calculator.algorithm(formula);

String formulaRes[]= new String[2];if (res > 0){

formulaRes[0] =formula;

formulaRes[1] =String.valueOf(res);

}else{returncreateProblem(range);

}returnformulaRes;

}

public String[] createProblem(intrange){

Random random= newRandom();int operatorCount = 1 + random.nextInt(3); //操作符的个数1-3

CreateInteger create= newCreateInteger();int[] operatorIndex = create.index(operatorCount,2, random); //操作符的下标//生成第一个操作数

int[] coprimeNumber1 =createCoprimeNumbers(range, random);int x = coprimeNumber1[0];int y = coprimeNumber1[1];

String s=shamToProperFraction(x, y);for(int i=0; i < operatorCount; i++){//生成剩下的操作数

int[] coprimeNumber =createCoprimeNumbers(range, random);int numx = coprimeNumber[0];int numy = coprimeNumber[1];

String currentOpreator=OPERATOR[operatorIndex[i]];if(currentOpreator.equals("+")){ //加法

x = x * numy + y *numx;

y= y *numy;

}else { //减法

int count = 0;while(x * numy - y * numx < 0){ //差为负数

coprimeNumber =createCoprimeNumbers(range, random);

numx= coprimeNumber[0];

numy= coprimeNumber[1];

count++;if (count >= 5){

numx= x - 1;

numy=y;

}

}

x= x * numy - y *numx;

y= y *numy;

}

String num=shamToProperFraction(numx, numy);

s+= currentOpreator +num;

}int greatFactor =greatFactor(x,y);

x/= greatFactor; //最终结果化简

y /=greatFactor;

String res=shamToProperFraction(x, y);

s+= "=";

String formulaRes[]={s, res};returnformulaRes;

}/*** 假分数转化为真分数

*@paramx 分子

*@paramy 分母

*@return

*/

public String shamToProperFraction(int x, inty){if (x >y){int n = x /y;

x= (x - n *y);if (x == 0){returnString.valueOf(n);

}return n + "'" + x + "/" +y;

}else if (x ==y){return "1";

}else if (y == 1){returnString.valueOf(x);

}else if (x == 0){return "0";

}return x + "/" +y;

}

}

计算结果函数

public intalgorithm(String s) {

Stack numStack = new Stack<>(); //放数字

Stack operatorStack = new Stack<>(); //放操作符

HashMap hashMap = new HashMap<>(); //存放运算符优先级

hashMap.put("(", 0);

hashMap.put("+", 1);

hashMap.put("-", 1);

hashMap.put("*", 2);

hashMap.put("÷", 2);

String formula= s.replaceAll(" ", "");for (int i = 0; i

StringBuilder digit= new StringBuilder(); //StringBuilder类中的方法主要偏重于对于字符串的变化,例如追加、插入和删除等,这个也是StringBuffer和String类的主要区别。

char c = formula.charAt(i); //将式子字符串切割为c字符

while (Character.isDigit(c)) { //判断字符是否为10进制数字,将一个数加入digit

digit.append(c);

i++;if (i

c=formula.charAt(i);

}else{break;

}

}if (digit.length() == 0){ //当前digit里面已经无数字,即当前处理符号

switch(c) {case '(': {

operatorStack.push(String.valueOf(c));//如果是( 转化为字符串压入字符栈

break;

}case ')': { //遇到右括号了计算,因为(的优先级最高

String stmp = operatorStack.pop(); //如果是),将符号栈栈顶元素取到

while (!operatorStack.isEmpty() && !stmp.equals("(")) { //当前符号栈里面还有+ - * /

int a = numStack.pop(); //取操作数a,b

int b =numStack.pop();int result = calculate(b, a, stmp); //计算

if(result < 0)return -1;

numStack.push(result);//将结果压入栈

stmp = operatorStack.pop(); //符号指向下一个计算符号

}break;

}case '=': { //遇到等号了计算

String stmp;while (!operatorStack.isEmpty()) { //当前符号栈里面还有+ - * /,即还没有算完

stmp =operatorStack.pop();int a =numStack.pop();int b =numStack.pop();int result =calculate(b, a, stmp);if(result < 0)return -1;

numStack.push(result);

}break;

}default: { //不满足之前的任何情况

String stmp;while (!operatorStack.isEmpty()) { //如果符号栈有符号

stmp = operatorStack.pop(); //当前符号栈,栈顶元素

if (hashMap.get(stmp) >= hashMap.get(String.valueOf(c))) { //比较优先级

int a =numStack.pop();int b =numStack.pop();int result =calculate (b, a, stmp);if(result < 0)return -1;

numStack.push(result);

}else{

operatorStack.push(stmp);break;

}

}

operatorStack.push(String.valueOf(c));//将符号压入符号栈

break;

}

}

}else { //处理数字,直接压栈

numStack.push(Integer.valueOf(digit.toString())); //Integer.valueof()返回的是Integer对象,而Integer.parseInt()返回的是int型

continue; //结束本次循环,回到for语句进行下一次循环,即不执行i++(因为此时i已经指向符号了)

}

i++;

}return numStack.peek(); //返回栈底数字即等式的答案。

}

判断结果函数

public voidstart(){

System.out.print("请输入待验证答案路径:");

Scanner scanner= newScanner(System.in);

String exerciseFilePath=scanner.next();

System.out.print("请输入程序生成答案文件路径:");

String answerFilePath=scanner.next();try{

List exerciseAnswers =exerciseFileReader(exerciseFilePath);

List answers =answerReader(answerFilePath);

List correct = new ArrayList<>();

List wrong = new ArrayList<>();int max =Math.max(exerciseAnswers.size(), answers.size());int num = 1;for (int i = 0; i < max; i++){if(exerciseAnswers.get(i).equals(answers.get(i))){

correct.add(String.valueOf(num++));

}else{

wrong.add(String.valueOf(num++));

}

}

File grade= new File("Grade.txt");if(grade.exists()){

grade.delete();

}if(grade.createNewFile()){

FileOutputStream gradeOutput= newFileOutputStream(grade);

PrintStream gradePrintStream= newPrintStream(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("判定完成");

}catch(FileNotFoundException e) {

System.out.println("文件不存在");

}catch(IOException e) {

System.out.println("文件读入异常");

}

}public List exerciseFileReader(String path) throwsIOException {

BufferedReader exerciseReader= new BufferedReader(newFileReader(path));

String exerciseAnswer= "";

List exerciseAnswers = new ArrayList<>();while ((exerciseAnswer = exerciseReader.readLine()) != null){

String[] split= exerciseAnswer.split("=");if (split[1] != null){

exerciseAnswers.add(split[1]);

}else{

exerciseAnswers.add(" ");

}

}returnexerciseAnswers;

}

测试

1.随机生成10道10以内的四则运算

0c9f78800672991d60ceed1207ed5154.png

ccf78f2de89dce7c48188062762383ab.png

2.判断题目的正确与否

7a81fe9f2afeacdb4c118465aae533eb.png

b9b91fb9823c8c2007a09ac6b2e9bd00.png

eee19e74b21b662d551be116feb16919.png

3.支持生成一万道题目

217ce9c3dcd5c3b2045b68642bd768bb.png

由于题目过多,因此直接在连接中打开

以上就是所有功能的测试

PSP表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

10

5

· Estimate

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

800

1200

Development

开发

480

630

· Analysis

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

60

30

· Design Spec

· 生成设计文档

60

80

· Design Review

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

30

45

· Coding Standard

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

30

30

· Design

· 具体设计

30

60

· Coding

· 具体编码

120

360

· Code Review

· 代码复审

30

45

· Test

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

120

120

Reporting

报告

120

120

· Test Report

· 测试报告

60

30

· Size Measurement

· 计算工作量

30

30

· Postmortem & Process Improvement Plan

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

30

30

合计

1200

1610

总结

在这次编程作业中,我和叶文涛同学一起讨论,他主要负责编写代码,后期的测试和报告则由我负责,在这一次的作业中,我也从伙伴身上学习到了很多,认识到自己与他人之间的差距,他在编程过程中也耐心的解答我的疑惑,在这个过程中不断的完善代码。两个人一起处理问题,互相汲取对方好的想法,有些细节没有考虑到的,另一个人可以帮忙补充,这样使得效率也大大提高。例如在我们进行最后测试的过程中,我发现当计算答案时如果答案为空则会出错,在这个情况下我们进行讨论之后也克服了这个问题。

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值