因为之前已经用JAVA写过程序,所以环境是已经配好了的,在此没有遇到太大的问题。 JAVA版本是JAVA8.0 编译器使用的是IDEA
阿超家里的孩子上小学一年级了,这个暑假老师给家长们布置了一个作业:家长每天要给孩子出一些合理的,但要有些难度的四则运算题目,并且家长要对孩子的作业打分记录。
作为程序员的阿超心想,既然每天都需要出题,那何不做一个可以自动生成小学四则运算题目与解决题目的命令行 “软件”呢。他把老师的话翻译一下,就形成了这个软件的需求:
程序接收一个命令行参数 n,然后随机产生 n 道加减乘除(分别使用符号+-*/来表示)练习题,每个数字在 0 和 100 之间,运算符在 2 个 到 3 个之间。
由于阿超的孩子才上一年级,并不知道分数。所以软件所出的练习题在运算过程中不得出现非整数,比如不能出现 3÷5+2=2.6 这样的算式。
练习题生成好后,将生成的 n 道练习题及其对应的正确答案输出到一个文件 subject.txt 中。
1、运算符存在差异。题目上的是(+-*/) 我的是(+-×÷)
2、我的文件名为“题目.txt”
"Talk is cheap. Show me the code."
结构
生成题目的类
public class FormulaMakerTest { /** * 生成题目的类 */ public LinkedList<String> questionMaker(int total) { //用于存放生成的运算式 String[] formulas = new String[total]; LinkedList<String> questionList = new LinkedList<>(); Numbers numbers = new Numbers(); OperationImpl operation = new OperationImpl(); OperationStringImpl operationString = new OperationStringImpl(); //循环开始的参数(一个用于外循环,一个用于循环) int start1; int start2; //用于保存每次运算的结果 int result; //用于标识运算是否会出现小数 int judge = 0; for(start1=0; start1<total; start1++) { //标识结果集的下标 //生成随2~3个的运算符 numbers.operationNumber = (int)(2+Math.random()*(3-2+1)); //存放每次运算的结果集 //生成3~4个参与运算的数字 numbers.numbers = new Integer[numbers.operationNumber+1]; for(start2=0; start2<=numbers.operationNumber; start2++) { numbers.numbers[start2] = (int)(0+Math.random()*(100-0+1)); } //生成运算符 numbers.operations = new Integer[numbers.operationNumber]; for(start2=0; start2<numbers.operationNumber; start2++) { numbers.operations[start2] = (int)(1+Math.random()*(4-1+1)); } //运算此表达式的运算结果(重点) //1、判断此算式是否满足条件(主要看除法是否满足) for(start2=0; start2<numbers.operationNumber; start2++){ if(numbers.operations[start2] == 4) { if(!operation.judgeDivision(numbers.numbers[start2], numbers.numbers[start2+1])) { //不满足 重新生成算式 judge++; }else { continue; } } } //若满足除法后无小数,则此算式成立 //算式中没有小数,可以生成表达式并打印 if(judge == 0) { //算式中没有小数,可以生成表达式并打印 formulas[start1] = operationString.operationSplicing(numbers.operationNumber, numbers.numbers, numbers.operations); System.out.println(formulas[start1]); }else { judge = 0; start1--; continue; } //调用计算函数计算结果 CalculateMaker maker = new CalculateMaker(); java.util.Queue<String> queue = new LinkedList<>(); queue = maker.calculateResult(numbers.numbers, numbers.operations); result = maker.calculate(queue); formulas[start1] += String.valueOf(result); questionList.add(formulas[start1]); } return questionList; } }栈进行四则运算的类
public class CalculateMaker { /** * 用于获得后缀表达式 * @return */ public Queue<String> calculateResult(Integer[] num, Integer[] operations) { //用于存放之前的算式 Queue<String> queue1 = new LinkedList<>(); //用于存放后缀表达式 Queue<String> queue2 = new LinkedList<>(); int i; //把运算式放入队列 for(i=0; i<num.length; i++) { queue1.offer(String.valueOf(num[i])); if(i<operations.length){ switch (operations[i]){ case 1: queue1.add("+"); break; case 2: queue1.add("-"); break; case 3: queue1.add("×"); break; case 4: queue1.add("÷"); break; default: break; } } } //用于存放运算符 Stack<String> stack = new Stack<>(); //用于标注队列中运算符的位置 i = 2; while(!queue1.isEmpty()) { //此位置是运算符 if(i%2==1) { i++; int num1, num2; //把运算符放进去 if(stack.empty()) { stack.push(queue1.poll()); }else { //取队首元素的值(用Unicode码来判断,加减号的值小于100,乘除号的值大于100) num1 = Translate.translateToInt(queue1.poll()); if(num1<100) { while (!stack.isEmpty()) { queue2.offer(stack.pop()); } stack.push(Translate.translateToString(num1)); }else { num2 = Translate.translateToInt(stack.peek()); if(num2<100) { stack.push(Translate.translateToString(num1)); }else { queue2.offer(stack.pop()); if(stack.isEmpty()) { stack.push(Translate.translateToString(num1)); }else { while(!stack.isEmpty()) { if(stack.isEmpty()) { stack.push(Translate.translateToString(num1)); break; } num2 = Translate.translateToInt(stack.peek()); if(num2<100) { stack.push(Translate.translateToString(num1)); break; }else { queue2.offer(stack.pop()); } } } } } } }else { i++; queue2.offer(queue1.poll()); if(queue1.isEmpty()){ while(!stack.isEmpty()) { queue2.offer(stack.pop()); } } } } //打印后缀表达式并返回 return queue2; } /** * 根据后缀表达式计算结果 * @param queue2 * @return */ public int calculate(Queue queue2) { /** * 用于进行后缀计算 */ OperationImpl operation = new OperationImpl(); //保存计算结果 int x = 0; int y = 0; int result = 0; Stack<String> stack = new Stack<>(); stack.push((String)queue2.poll()); while(!queue2.isEmpty()) { String str = (String) queue2.poll(); //遇到运算符,出栈运算,结果入栈 if(!operation.judgeOperation(str)) { stack.push(str); }else { y = Integer.valueOf(stack.pop()); x = Integer.valueOf(stack.pop()); result = operation.calculateNumber(x, y, str); stack.push(String.valueOf(result)); //如果最终只有一个元素,则为计算的结果 if(stack.size() == 1 && queue2.isEmpty()) { return Integer.valueOf(stack.pop()); } } } return y; }}
主函数
public static void main(String[] args) { //输入想要的题目数 System.out.println("请输入想要创建题目的数目:"); //生成题目的数目 Scanner scanner = new Scanner(System.in); int total = scanner.nextInt(); //生成题目生成器 FormulaMakerTest maker = new FormulaMakerTest(); //题目集 LinkedList<String> questionList = maker.questionMaker(total); System.out.println(questionList); //将题目存入文件中 FileWriting writing = new FileWriting(); writing.WriteStringToFile(questionList); }控制台打印的题目
文件中保存的题目
官网上下确实有点慢,找同学要的其他资源下的。
指令:
git config --global user.name "用户名"
git config --global user.email 邮箱
进入这里 点这里,复制这里的url
在Git的文件夹下创建一个新的文件夹,在新的文件夹内右键选择Git Bash Here, 然后再在界面上输入git clone + 刚才复制网址,即 https://github.com/Cherish599/AchaoCalculator
成功后便会多出一个文件夹,在里面创建一个和自己github用户名一致的文件,将程序源码放进去。
然后转到AchaoCalculator文件目录下(cd 文件的路径) 然后输入git add . , 再输入git commit -m "分支名称",最后输入 输入 git push,在这里会弹出框让你输入GitHub的用户名和密码即可
最后在GitHub上就能看到你提交的文件啦
1、第一次接触GitHub,大多是看着教程操作的,以后需要多多熟悉
2、很多指令不熟悉,有的教程上的地方我用起来会出现错误,在其他地方找了解决的办法
因为在编程过程中有很多需要单元测试的地方,也有很多bug需要及时修改,所以没有细致的记录,在此简单的描述一下
JAVA的单元测试可以基于Junit,并需要在测试的方法前加上@Test注解且测试方法不能存在参数
同时也可以基于main()方法来测试,并在需要的地方输出语句
1、表达式的生成(字符串的拼接)出现错误。因为运算符是运用1~4的随机数来保存的,所以生成算式时需要转化为加减乘除对应的符号,思考后得以解决。
2、后缀表达式生成出现错误。因为对中缀表达式转化为后缀表达式的理解还存在一些偏差。在仔细阅读概念,并不断得打印后缀表达式后,找出了代码中出现的问题,最后得以解决
3、得到后缀表达式后计算结果出现错误。后缀表达式存在一个队列中,队列中元素的出队,以及数字元素的压栈、出栈操作出现问题。在条件语句中多次进行打印操作后,找出了错误出现的位置,找到原因,最终得以解决。
4、如果除法存在小数如何解决。我才用的方法是将此次循环作废,即将循环因子的值减一,并不进行拼接操作。
单元测试时会存在许多问题,解决了这些问题,也就是进行了回归测试,同样在编程过程中有很多的回归测试,所以没有过多去记录
这是进行单元测试后,再进行回归测试才得出的判断运算结果是否为小数的方法。
得出的判断方法:看两个整数相除后的结果与其强转成浮点型后的结果是否一样,一样则是整数,反之则是小数
说实话感觉这次作业还是很有难度的。主要是编写代码部分就需要大量的时间与精力。数据结构在学栈的部分学习过四则运算优先级判断,但是当时没有用代码实现,所以还花时间去学习了一下。
学习Git的使用过程中,好在有很多文章可以参考,虽然陌生但是操作起来还是比较容易。
环境因为是以前就配好的,同时单元测试和回归测试其实在代码的编写中以及有所使用了,这方面进行的还是比较顺利。
总之这次作业还是让我收获颇丰,无论是对编程语言JAVA,还是数据结构中栈和队列,以及Git的使用都得到了很好的练习
转载于:https://www.cnblogs.com/nyima/p/11537353.html
相关资源:JAVA上百实例源码以及开源项目