需求分析
首先明确项目需要,一个可以定做小学四则运算的程序。所以需要我们能够随机生成不同的四则运算,范围应在100以内,包含“+,-,*,÷”四种操作。要求:不存在小数,题目尽量不重复。
功能设计
基本功能应当包括,读入用户想要定制的算式数,以及对应的运算符数量,然后生成对应数目和难度的四则运算式子。并由程序自己计算,给出相应的答案。
扩展功能可以用:在算式中包含括号,计算存在真分数的式子。
设计实现
由计算机生成随机的第一个数字、运算符、后续数字、完成计算、显示结果等等。
在生成后续数字时,可以限定生成条件以保证运算结果不会出现分数和负数的情况。
代码详解
Lib类中
1 static String createFormula() 2 { 3 int digital, sign = 0; 4 char symbol = 0; 5 String formula = ""; 6 7 digital = (int)(Math.random()*20); 8 formula = formula + digital; 9 10 for(int i=0; i<5; i++) 11 { 12 if(sign >= 2) 13 sign = (int)(Math.random()*2); 14 else sign = (int)(Math.random()*4); 15 16 if(sign == 0) { 17 symbol = ‘+‘; 18 digital = (int)(Math.random()*20+1); 19 } 20 else if(sign == 1) { 21 symbol = ‘-‘; 22 digital = (int)(Math.random()*digital+1); //??è¥é?ò???digital 23 } 24 else if(sign == 2) { 25 symbol = ‘*‘; 26 digital = (int)(Math.random()*(100/(digital+1))+1); 27 28 } 29 else if(sign == 3) { 30 symbol = ‘÷‘; 31 for(int j=2; j<=digital; j++) 32 if(digital%j == 0) { 33 digital = j; 34 break; 35 } 36 } 37 formula = formula + symbol + digital; 38 } 39 return formula; 40 }
使用createFormula()创建算式,:
1、随机生成算式第一个数(20以内)
2、依次确定(生成)五个运算符以及第二个数字
(1)sign用于避免出现连续的“乘”、“除”运算(原理:sign随机确定运算符,sign的上一个值>=2时,后面生成的运算符只有“+”、“-”)
(2)为避免出现负数,当sign为“-”时,后一个数的生成范围为“比上一个数小”
(3)当sign为“×”时,为避免出现大雨100的结果,第二个数的生成范围为[0,100/上一个数]
(4)当sign为“÷”时,为保证不出现分数,第二个数为 [2~第一个数] 这个范围内找“第一个数的因数”生成
3、实现字符串拼接
static int answerFormula(String formula) { char[] charArray = formula.toCharArray(); int[] stackForInt = new int[10]; char[] stackForChar = new char[10]; int topOfInt = -1, topOfChar = -1, num = 0; for(int i=0; i<charArray.length; i++){ //System.out.println(i+" :"+topOfInt+" "+topOfChar); if(Character.isDigit(charArray[i])) { num = num*10 + charArray[i]-‘0‘; if(i == charArray.length - 1) stackForInt[++topOfInt] = num; } else { stackForInt[++topOfInt] = num; num = 0; if(topOfChar == -1) stackForChar[++topOfChar] = charArray[i]; else if(charArray[i]==‘*‘ || charArray[i]==‘÷‘) { if(stackForChar[topOfChar] == ‘*‘ || stackForChar[topOfChar] == ‘÷‘) { int num1 = stackForInt[topOfInt--]; int num2 = stackForInt[topOfInt--]; char symbol = stackForChar[topOfChar--]; if(symbol == ‘*‘) stackForInt[++topOfInt] = num1 * num2; else if(symbol == ‘÷‘) stackForInt[++topOfInt] = num2 / num1; stackForChar[++topOfChar] = charArray[i]; } else if(stackForChar[topOfChar] == ‘+‘ || stackForChar[topOfChar] == ‘-‘) { stackForChar[++topOfChar] = charArray[i]; } } else if(charArray[i]==‘+‘ || charArray[i]==‘-‘) { if(topOfChar == -1) stackForChar[++topOfChar] = charArray[i]; else { while(topOfChar != -1) { int num1 = stackForInt[topOfInt--]; int num2 = stackForInt[topOfInt--]; char symbol = stackForChar[topOfChar--]; if(symbol == ‘+‘) stackForInt[++topOfInt] = num1 + num2; else if(symbol == ‘-‘) stackForInt[++topOfInt] = num2 - num1; else if(symbol == ‘*‘) stackForInt[++topOfInt] = num1 * num2; else if(symbol == ‘÷‘) stackForInt[++topOfInt] = num2 / num1; } } stackForChar[++topOfChar] = charArray[i]; } } } while(topOfChar!=-1) { int num1 = stackForInt[topOfInt--]; int num2 = stackForInt[topOfInt--]; char symbol = stackForChar[topOfChar--]; if(symbol == ‘+‘) stackForInt[++topOfInt] = num1 + num2; else if(symbol == ‘-‘) stackForInt[++topOfInt] = num2 - num1; else if(symbol == ‘*‘) stackForInt[++topOfInt] = num1 * num2; else if(symbol == ‘÷‘) stackForInt[++topOfInt] = num2 / num1; } return stackForInt[0]; }
答案部分:使用中序运算式转成后序运算式以计算表达式
1、stackForInt:模拟int栈
2、stackForChar:模拟字符栈
3、topOfChar / topOfInt:模拟栈顶
将string类型的算式转化成数组
用中序运算读取字符数字并计算得出答案
static void printFormula(String[] formulaList, int n)throws IOException { FileOutputStream fs = new FileOutputStream(new File("result.txt")); PrintStream p = new PrintStream(fs); p.println("2016012036"); for(int i=0; i<n; i++) p.println(formulaList[i]); p.close(); }
在result中显示结果(优先显示学号信息)
在Main中
public static void main(String args[]) { Scanner input = new Scanner(System.in); int n; n = input.nextInt(); String[] formulaList = new String[50]; for(int i=0; i<n; i++) { formulaList[i] = Lib.createFormula(); //System.out.println(formula); int answer = Lib.answerFormula(formulaList[i]); formulaList[i] = formulaList[i] + ‘=‘ + answer; } try { Lib.printFormula(formulaList, n); } catch(IOException ioe) { ioe.printStackTrace(); } }
主函数循环n次,生成n个式子并完成计算,catch异常。
结果展示
基本实现了基础功能
用“模块化”将代码分块实现,避免了很多不必要的麻烦,整个项目实现起来也更加流畅,思路更加清晰,对效率的提高有很大帮助。
PSP展示
这次作业战线拉得特别长,从分块方式等开始慢慢构思,很多思考过程都是在平时的生活中完成的,而且在实现过程中因为不熟练,每天的进度非常低,所以并没有使用PSP……而且之前也败在没有真正习惯事先定好时间计划,所以实在没办法进行PSP展示。
原文地址:https://www.cnblogs.com/yfxxg/p/8646221.html