做业具体要求连接:https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/997android
具体实现功能以下:ios
功能1:支持出题4个数的四则运算题目,全部题目要求做者有能力正确回答。(+10)git
功能2:在功能1的基础上,支持括号。(+15)web
功能3:限定题目数量,“精美”打印输出,且要避免重复,最好能输出到.txt文件中。且对输入题目数进行限定,题目数量必须是正整数。(+10)算法
功能4:支持分数出题和运算。(不完成此题不倒扣分数)编程
功能5:可把程序改为GUI版/web版/移植为android,ios版。dom
这次做业完成是以“结对编程”的形式完成,个人伙伴是刘淑霞,她的博客地址为:http://www.cnblogs.com/liusx0303/学习
这篇博客主要由以下几个方面讲述:spa
1.每一个功能的重点,难点。.net
2.如何解决重点难点以及收获
3.运行截图
4.结对编程体会。
5.合做过程。
6.版本控制。
一,每一个功能的重点,难点
(1)功能一的重点难点
重点难点1:应该选择什么样的输入,操做数和运算符随机产生仍是用户本身输入,若是随机产生要如何操做,若是用户本身输入要以什么样的形式输入
重点难点2:如何处理四则运算算式。
重点难点3:将输入的结果与正确结果比较,而后按照要求输出。
(2)功能二的重点难点
功能二的要求:在功能一要求的基础上加上有括号的运算。
重点难点:加上有括号的运算,咱们当初分析的时候是用括号匹配的方法,括号优先级最高,优先算括号里面的算式。
(3)功能三的重点难点
功能三的要求:输入题目道数,而后输出四则运算算式以及结果到.txt文件中,注意输出结果右对齐,与算式有必定的距离。
重点难点:将输出放到.txt文件中。
(4) 功能四的重点难点
功能四的要求:支持分数运算,不加括号,输出也是用分数的形式输出,例如1/2 + 2/3 +1+1=3 1/6。
重点难点:支持分数运算,经过通分来进行运算,结果是最简分数(几又几分之几)。
二,合做中如何解决重点难点以及收获
(1)功能一:
由于要支持出题4个数的四则运算题目,针对的用户是初中生,因此题目难度不能太过于简单,也不能过于困难。若是题目随机生成,有太大的随机性,且容易产生重复,用随机数自动生成四个数的四则运算也会比较麻烦,考虑的状况会比较繁多。开始,咱们用random生成两个数加减乘除的运算,运行成功,实现支持4个数的四则运算的时候,由于要考虑的状况太过于复杂,写完就400多行代码了,且题目易重复。想一想功能一实现就这样艰难。因而想经过本身输入出题,而后让人作的形式实现,且本身出题能够避免重复。题以字符串的出现,而后对字符串进行处理,而后对题进行计算。
对字符串进行处理,判断表达式格式是否正确的代码实现以下:
//检查表达式格式是否正确 public static boolean checkFormat(String str) { // 校验是否以“=”结尾 if ('=' != str.charAt(str.length() - 1)) { return false; } // 校验开头是否为数字或者“(” if (!(isCharNum(str.charAt(0)) || str.charAt(0) == '(')) { return false; } char c; // 校验 for (int i = 1; i < str.length() - 1; i++) { c = str.charAt(i); if (!isCorrectChar(c)) {// 字符不合法 return false; } if (!(isCharNum(c))) { if (c == '-' || c == '+' || c == '*' || c == '/') { if (c == '-' && str.charAt(i - 1) == '(') {// 1*(-2+3)的状况 continue; } if (!(isCharNum(str.charAt(i - 1)) || str.charAt(i - 1) == ')')) {// 若符号前一个不是数字或者“)”时 return false; } } if (c == '.') { if (!isCharNum(str.charAt(i - 1)) || !isCharNum(str.charAt(i + 1))) {// 校验“.”的先后是否位数字 return false; } } } } return isBracketCouple(str);// 校验括号是否配对 }
(2)功能二:
对于在功能一的基础上,实现括号。咱们是利用栈实现括号匹配算法。而且使用了map对运算符进行了优先级处理。
符号的优先级处理代码以下:
public static final Map<Character, Integer> symLvMap = new HashMap<Character, Integer>();// 符号优先级map static { symLvMap.put('=', 0); symLvMap.put('-', 1); symLvMap.put('+', 1); symLvMap.put('*', 2); symLvMap.put('/', 2); symLvMap.put('(', 3); symLvMap.put(')', 1); }
括号匹配的代码以下:
//校验括号是否配对 public static boolean isBracketCouple(String str) { LinkedList<Character> stack = new LinkedList<Character>(); for (char c : str.toCharArray()) { if (c == '(') { stack.add(c); } else if (c == ')') { if (stack.isEmpty()) { return false; } stack.removeLast(); } } if (stack.isEmpty()) { return true; } else { return false; } }
(3)功能三:
1.对于输入题目道数是正整数的判断,不能是英文(test),负数(-100),浮点数(3.5)。开始是定义了一个int型的变量,而后对变量进行正整数判断,把负整数去掉。
可是当输入英文,负数和浮点数的时候,运行的时候报错了。后来采用字符串的格式进行输入,而后对字符串的进行在数值范围的判断。
判断输入题目道数是正整数的代码以下:
//判断输入的题目数是否为正整数 public boolean judgeInput(String str) { boolean flag=true; for(int j=0;j<str.length();j++) { if(!(str.charAt(j)>=48&&str.charAt(j)<=57)) { System.out.println("题目数量必须是 正整数。"); flag=true; break; } else { flag=false; } } return flag; }
2.将题目和答案输出到.txt文件中
实现代码以下:
//将表达式写入文件answer.txt try { if (!file.exists()) { file.createNewFile(); } FileWriter writer = new FileWriter(file,true); if(true) { results = System.getProperty("line.separator")+results; } writer.write(results); writer.flush(); writer.close(); } catch (IOException ex) { ex.printStackTrace(); }
(4)功能四:
方法是先求出两个分数分母的最小公倍数,通分后,再对两个分子的加减乘除,最后约简结果分数的分子和分母,即用分子分母的最大公约数分别除分子和分母。再按顺序输入分子和分母,在控制台上输出其运算结果。
求最大公约数的代码以下:
static int gcd(int m,int n)
{ int t,r;//展转相除法 if(m < n) { t = m; m = n; n = t; } while(n != 0) { r = m%n; m = n; n = r; } return m; }
求最小公倍数代码以下:
static int lcm(int m,int n)
{ int i = gcd( m,n); int j = (m/i)*(n/i)*i; return j; }
收获:
1.在制定代码规范的时候,由于咱们都有本身的习惯,因此在制定规则时讨论了较长时间,可是彼此为对方考虑,都各自让步,最终制定了两我的都能接受的代码风格规范。这告诉咱们,要多为对方考虑一点,这样才能使合做更愉快,后面实现的过程当中也证实了这一点。
2.在考虑实现出题的时候,我和霞都不约而同的用随机数生成出题。以为可简单了,认为一两个小时就能完成功能一,开始实现起来两个数的加减乘除很快就完成了,而后按照老师要求要完成四个数的加减乘除,实现起来状况就很复杂了,咱们完成一个demo的时候就差很少500行代码了,花费了3个多小时,而且有出题重复的状况。后来就一块儿讨论用本身出题的方式解决,能够避免重复,而且能够控制难度。实现的过程,咱们让结果返回double,由于除法确定会有小数的出现。在一块儿讨论实现的过程当中,知道了不要把一个问题看得太简单,否则容易眼高手低,要明白需求,再开始作事。
3.在对输入题目以字符串的形式写表达式时,要对输入的表达式作各类判断,否则表达式会出错,操做数是否是数字,操做数是否是“+,-,*,/”,最后是否是以等号结尾。一我的老是会疏忽不少小细节,幸运的是,我和霞结对编程,总能考虑到对方疏忽的一些小问题。
4.在结对编程的过程当中,一我的在编,另一我的在旁边盯着,老是可以及时提醒对方触犯的代码规范和犯的语法错误,相互批评,指导,和交流,比一我的编程好玩多了,编程速度虽然没有一我的快,可是两我的编程的质量更高,错误更少。
5.功能3将结果输出到.txt文件中,运行输入表达式的时候,打开.txt文件一看结果都在,觉得本身成功了,可是可开心了,而后霞察觉文件的表达式不少,且有重复,咱们恍然大悟,知道本身原始数据没有清空,而后两我的寻找解决对策,后来决定在输入题目语句后面将.txt赋空值,两我的一块儿发现和解决问题的过程真是很nice。
三,运行截图
功能1,2截图
功能3截图:
四,结对编程体会
结对编程以前,我并无发现结对编程的好处,但在共同完成做业的时候,切身感觉到结对编程的好处。两人合做的过程,是一段“美好且痛苦又幸福”的体验。
在四个功能的实现过程当中,咱们碰见了不少没有想到的困难。在碰见一个难点的时候,或者运行时出错的时候,两我的一块儿想办法解决,两我的虽然都有不同的想法,可是都是为了解决同一个问题,当谁的办法可以解决问题的时候,咱们都特别开心。完成做业的同时,我得到了知识,也从对方的身上学到了不少,学习能力和思惟方式都获得了进步,发现结对编程会使两我的加在一块儿,会达到1+1>2的效果。
五,合做过程
咱们结对编程是在软件所220完成,附上咱们两人结对编程的照片。
六,版本控制