代码仓库:https://git.coding.net/theMostCute/sizeYunSuanO.git
需求分析:
- 程序可接收一个输入参数n,然后随机产生n道加减乘除(分别使用符号+-*÷来表示)练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间
- 每个练习题至少要包含2种运算符。不能存在分数、负数与非整数。
- 练习题生成好后,将你的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致
功能设计:
- 判断n是否合法
- 生成n个题目,题目满足要求
- 判断题目的结果是否为分数、负数与非整数
设计实现:
由于自己大部分时间都是学习的前端开发,对JavaScript比对Java熟悉,所以采取的方法为先用JavaScript写出功能,再转为Java。在下面的算法解说中,也会采取分开JavaScript解说和Java解说
因为对Java语言的不熟悉,有很多细节进行了阉割。
四则运算式求出的思路:用一组数组取随机个数的运算符,再用另一个数组取随机数,再混合两个数组,把混合后的数组转换为字符串,然后用后缀表达式进行求出
需要:
设计能随机取符号的方法
Java中没有eval函数,所以要宁外写后缀表达式。
算法详解:
1.判断输入的n为正整数:
JavaScript版:通过正则表达式
var r = /^+?[1-9][0-9]*$/ ;//正整数+0 if(r.test(n)){ chuti(n); }else{ alert("请输入正确正整数!!!");
由于对Java语言不熟悉,在Java版只添加了0<n<1000
2.生成题目:用一组数组取随机个数的运算符,再用另一个数组取随机数,再混合两个数组,把混合后的数组转换为字符串
这个部分的算法思路都是一样的:
JavaScript:
for(i=0;i<n;i++){ var oo=Math.floor((Math.random()*10+4)/2);//有多少个符号 var aAarr=[];//符号数组 for(q=0;q<oo;q++){ var m=Math.floor(Math.random()*100+1);//随机符号 aAarr[q]=fuhao(m); } var oo1=oo+1;//有多少数字 var oAarr=[];//随机数数组 for(z=0;z<oo1;z++){ oAarr[z]=Math.floor(Math.random()*100+1);//随机数 } var bigArarr=[]; for(p=0;p<oo1;p++){ //将符号与随机数混合 j=2*p; bigArarr[j]=oAarr[p]; l=j+1; bigArarr[l]=aAarr[p]; } var suanshi=bigArarr.toString();
var osuan=suanshi.replace(/,/g,'');
Java:Java的数组要求比JavaScript严格很多,在这个部分一直报错
for(int i=0;i<no;i++){ int oo=(int)Math.floor((Math.random()*10+4)/2);//有多少个符号 String aAarr[]=new String[oo];//符号数组 for(int q=0;q<oo;q++){ int m=(int)Math.floor(Math.random()*100+1);//随机符号 aAarr[q]=a.fuhao(m); } int ooo=oo+1;//有多少数字 int oAarr[]=new int[ooo];//随机数数组 for(int z=0;z<ooo;z++){ oAarr[z]=(int)Math.floor(Math.random()*100+1);//随机数 } int aaa=oAarr.length+aAarr.length; //System.out.println(aaa); String bigArarr[]=new String[aaa]; for(int p=0;p<aaa;p++){ //将符号与随机数混合 int j=2*p; int l=j+1; if(p<oAarr.length){ bigArarr[j]=oAarr[p]+""; } if(p<aAarr.length){ bigArarr[l]=aAarr[p]; } // System.out.print(bigArarr[p]); } StringBuffer sbb = new StringBuffer(); for(int wq = 0; wq < bigArarr.length; wq++){ sbb. append(bigArarr[wq]); }
3.算出结果
JavaScript:eval函数超级强大,只需要一行代码
osan=eval(osuan);
Java:没有eval函数,所以用了后缀表达式,在童宇欣小姐姐的帮忙下,并参考了她的代码,搞定了它
for (int j = -1; j < len - 1; j++) {//把题目字符串进行拆分,拆分出数字和运算符,分别进行存储 if (question.charAt(j + 1) == '+' || question.charAt(j + 1) == '-' || question.charAt(j + 1) == '*' || question.charAt(j + 1) == '÷' || question.charAt(j + 1) == '(' || question.charAt(j + 1) == ')' || j == len - 2) { if (j == -1) {//如果第一个就是运算符,即左括号,存储在操作符栈中 operate.push(question.charAt(0)); } else if (j == len - 2) {//如果到字符串的最后了,直接存储到数字栈中 number.push(question.substring(k)); break; } else { if (k <= j) { number.push(question.substring(k, j + 1));//是数字的话存储到数字这个栈中 } if (operate.empty() || question.charAt(j + 1) == '(') { operate.push(question.charAt(j + 1)); } else if ((operate.peek() == '+' || operate.peek() == '-') && (question.charAt(j + 1) == '*' || question.charAt(j + 1) == '÷')) { operate.push(question.charAt(j + 1)); } else if (operate.peek() == '(') { operate.push(question.charAt(j + 1)); } else if (question.charAt(j + 1) == ')') { number.push(String.valueOf(operate.pop())); if (!operate.empty()) { operate.pop(); } } else { if(operate.peek()==question.charAt(j + 1)){ same++; } number.push(String.valueOf(operate.pop())); operate.push(question.charAt(j + 1)); } } k = j + 2; } }
4.判断题目的结果是否为分数、负数与非整数
JavaScript:正则表达式
var r = /^+?[1-9][0-9]*$/ ;//正整数+0 if(osan<0){ //判断为非负数 i=i-1; }else if(r.test(osan)){ //判断为正整数+0 var para=document.createElement("p"); var node=document.createTextNode(osuan+"="+(osan)); para.appendChild(node); timu.appendChild(para); }else{ i=i-1; }
5.随机取符号的方法:利用取随机数的方法,进行范围规范
JavaScript:
function fuhao(o){ var oyo; if(0 <o&&o<25){ oyo="+"; }else if(25<o&&o<50){ oyo="-"; }else if(50<o&&o<75){ oyo="*"; }else{ oyo="/"; } return oyo; }
Java:原理一样
public static String fuhao(double o){ String oyo; if(0<o&&o<25){ oyo="+"; }else if(25<o&&o<50){ oyo="-"; }else if(50<o&&o<75){ oyo="*"; }else{ oyo="÷"; } return oyo; }
6.Java文件导出
try { ps = new PrintStream("result.txt"); System.setOut(ps);// 把创建的打印输出流赋给系统。即系统下次向 ps输出 } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }// 创建一个打印输出流
测试运行
JavaScript的页面展示:
总结:
本次作业暴露出了我自身Java能力的欠缺,以及感受到了不同语言之间的强大差异,用JavaScript写,包含了必要的HTML代码一起才90+行代码,而用Java得用150+行代码才可以出来。
最大的区别是在于eval函数和正则表达式的应用上。
用JavaScript写出所有功能花了一个多小时,而把JavaScript转为Java却花了我一天多,这还是我求助各位大佬和度娘的结果,但还是有很多细节并没有处理好。
所以,经过本次学习,我深刻的知道自己该好好的复习复习Java了
PSP
PSP2.1 |
任务内容 |
计划共完成需要的时间(min) |
实际完成需要的时间(min) |
Planning |
计划 |
10 |
10 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
10 |
10 |
Development |
开发 |
500 |
2000+ |
Analysis |
需求分析 (包括学习新技术) |
20 |
20 |
Design Spec |
生成设计文档 |
10 |
10 |
Design Review |
设计复审 (和同事审核设计文档) |
5 |
5 |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
1 |
1 |
Design |
具体设计 |
20 |
40 |
Coding |
具体编码 |
400 |
2000+ |
Code Review |
代码复审 |
20 |
20 |
Test |
测试(自我测试,修改代码,提交修改) |
15 |
30 |
Reporting |
报告 |
20 |
30 |
Test Report |
测试报告 |
10 |
20 |
Size Measurement |
计算工作量 |
1 |
1 |
· |
· |