题目集一难度比题目集二、三的难度低,但是它的题量比较大的,总共有八道题目,考察了输入输出语句、if-else语句、switch语句、for语句和数组,是这三次题目集中最简单的一次题目。
题目集二的难度相较于题目集一有所提高,总共有五道题目,前两道题目考察了if-else语句和数组,后面三道题目主要是围绕着日期,通过设计方法来解题。
题目集三的难度是这三次题目集中最难的一次,总共有三道题目,通过类设计来解决一些题目。前面两个道题目是已经设计好了类去实现功能,后面一道题目是自己设计类来解决题目。
Source Monitor生成表内容
该题除Main类外,无其他类。所以不给出Power Designer绘制的类图。
解释:O复杂度为23,代码状况非常复杂,可测性低,维护成本高。总共75行,通过简单的语句判断输入内容是否合法,以及属于哪种三角形。
心得:代码应规范,简洁,完整。本题对类的设计以及其他知识点未作要求,题目简单。
Source Monitor生成表内容
该题除Main类外,无其他类。所以不给出Power Designer绘制的类图。
解释:O复杂度为13,代码状况复杂,可测性中,维护性中。总共82行,实现了计算下一天的功能。除main方法之外,boolean checkInputValidity()
判断输入的年月日是否合法,booleasn isLeapYear()
来判断是否为闰年,void nextDate()
来计算下一天
心得:在计算下一天时要考虑跨年情况的出现,年份要+1,月份要变成1月份,日期做出相应的改变。在对年月日问题时,应该了解2月份的特殊之处,闰年2月份有29天,平年则是28天。
Source Monitor生成表内容
该题除Main类外,无其他类。所以不给出Power Designer绘制的类图。
解释:O复杂度15,代码状况复杂,可测性中,维护性中。总共85行,实现了计算出前后几天的年月日。除main方法之外,boolean checkInputValidity()
判断输入的年月日是否合法,booleasn isLeapYear()
来判断是否为闰年,void result()
计算出前后几天,int secday()
返回2月份的天数。
心得:思路和7-4类似,在此不再赘述。
Source Monitor生成表内容
Power Designer类图
解释:O复杂度13,总共112行,通过类来实现求下一天,总体思路和7-5类似。
心得:类的属性都必须是private
,方法要是public
.类的属性不能是由计算得出的,必须符合的类的内容。
Source Monitor生成表内容
Power Designer类图
解释:O复杂度12,代码状况复杂,可测性中,维护性中。总共164行,实现一元多项式求导。设计Derivation
类来对多项式求导,boolean check()
来判断多项式是否输入合法,List<String> distill1()
提取含未知数的项,List<String> distll2()
提取项中的指数和系数,List<String> derivation()
对指数和系数求导,String result()
缝合各个项成为字符串。
心得:复杂问题细化成一个一个小步骤,设计合理的类,来实现功能。理解世界上的万事万物的能设计成为类。
问题:
? 1.思考不够全面,不能通过闰年最后一天。
总结:
? 1.思考应该全面清晰,不要出现遗漏,确保基本无误后在写代码。
改进后实现下一天代码:
public static void nextDate(int year,int month,int day) {
int[] m1 = {0,31,28,31,30,31,30,31,31,30,31,30,31};
if(month == 12) {
if(day < m1[month])
day++;
else {
year++;
month = day =1;
}
}
else if(month == 2) {
if(isLeapYear(year)) {
if(day < 29)
day++;
else {
month++;
day = 1;
}
}
else {
if(day < 28)
day++;
else {
month++;
day = 1;
}
}
}
else if(day < m1[month])
day++;
else {
day = 1;
month++;
}
System.out.printf("Next date is:%d-%d-%d",year,month,day);
}
/**
测试结果
2000 12 31
Next date is:2001-1-1
*/
问题:
1.二月到三月,三月到二月,一十二月到一月,一月到一十二月,四个比较特别的月份刚开始的时候没有考虑清楚,导致无法通过全部测试点。
2.过度解读,没有看清题目给的条件。题目中出现过输入一个取值范围在[-10,10] 之间的整型数n
,所以不存在跨两个月份的情况存在。
总结:
1.分类清晰,了解特殊情况的特殊之处。它为什么特殊,和普通情况下实现的区别在哪里,是否需要提取出来单独判断。
改进后实现结果的部分方法:
public static void result(int year,int month,int day,int n) {
int[] m1 = {31,31,28,31,30,31,30,31,31,30,31,30,31};
int t1 = month;
int t2 = day;
int t3 = 0;
if(t1 == 2 & t2 + n > (t3 = secday(year))) {
month++;
day = t2 + n - t3;
}
else if(t1 ==3 & t2 + n <= 0) {
month--;
day = secday(year) + t2 + n;
}
else if(t1 == 12 & t2 + n > 31) {
year++;
month = 1;
day = t2 + n - 31;
}
else if(t1 == 1 & t2 + n <= 0) {
month = 12;
year--;
day = 31 + t2 + n;
}
else if(t2 + n > (t3 = m1[month])) {
day = t2 + n - t3;
month++;
}
else if(t2 + n <= 0) {
day = m1[month - 1] + t2 + n;
month--;
}
else
day = t2 + n;
System.out.printf("%d days ago is:%d-%d-%d",-n,year,month,day);
}
/**
测试结果
2000 3 3 5
5 days ago is:2000-2-27
2000 2 28 -9
-9 days ago is:2000-3-8
2000 12 30 -8
-8 days ago is:2001-1-7
1999 1 1 7
7 days ago is:1998-12-25
*/
问题:
1.没有认真阅读指导书上的内容,对输入和输出的内容做出自己的判断,而不是按照指定的内容输出
2.最后一个合法测试点未能通过,一直没能知道为什么
3.类设计单一,只设计了一个求导类,而没有去设计其他的类。指数、系数、常项和未知项也能是一个类
4.编译过程中出现字符串指向空错误,不能调用指向空的对象的方法
总结:
1.认真阅读给出的已知条件,不要把时间花费在大量的无意义的事情上
2.世界上的万事万物都能是类,不要把思维停留在c语言的函数思维范围内,局限自己的思维
3.不能充分的运用自己所学的正则表达式,刚开始就只是判断输入合法的时候用了正则表达式,不能灵活的运用正则表达式,把自己局限于以前的思维,不断地用if-else
语句去判断指数和系数
4.避免对指向空的引用进行操作
改进后含未知量提取和求导系数和指数
改进后仍然无法通过最后一个测试点,所以不给出测试数据。
public List<String> distill2() {
List<String> list = new ArrayList<String>();
list = distill1();
List<String> newList = new ArrayList<String>();
Iterator<String> itr = list.iterator();
int k = 0;
while(itr.hasNext()) {
String each = (String)itr.next();
String regex1 = "[\\-\\+]?[x].*";
String sa = null;
String sb = null;
boolean flag = true;
if(Pattern.matches(regex1,each)) {
String t = each.replaceAll("[x].*","x");
sa = t.replace("x","1");
flag = false;
}
String regex2 = "[\\+\\-]?\\d+";
Pattern p2 = Pattern.compile(regex2);
Matcher m2 = p2.matcher(each);
while(m2.find()) {
String ts = m2.group();
if(flag) {
sa = ts;
flag = false;/
}
else {
sb = ts;
}
}
if(sb == null) {
sb = "1";
}
String tt = sa + " " + sb;
newList.add(k++,tt);
}
return newList;
}
public List<String> derivation() {
List<String> list = new ArrayList<String>();
list = distill2();
List<String> newList = new ArrayList<String>();
Iterator<String> itr = list.iterator();
int k = 0;
while(itr.hasNext()) {
String each = (String)itr.next();
String[] ts = each.split(" ");
BigDecimal a = new BigDecimal(ts[0]);
BigDecimal b = new BigDecimal(ts[1]);
BigDecimal b1 = new BigDecimal("1");
BigDecimal b11 = new BigDecimal("-1");
boolean flag = false;
BigDecimal b0 = new BigDecimal("0");
BigDecimal ta = a.multiply(b);
BigDecimal tb = b.subtract(b1);
if(b.compareTo(b0) > 0 && a.compareTo(b0) > 0) {
flag = true;
}
if(a.compareTo(b0) < 0 && b.compareTo(b0) < 0) {
flag = true;
}
String ea = ta.toString();
String eb = tb.toString();
if(tb.compareTo(b0) == 0) {
eb = null;
}
else {
eb = eb.replace("+","");
eb = "x^" +eb;
}
if(flag) {
ea = "+" + ea;
}
if(eb != null) {
ea = ea + "*";
}
String t = ea;
if(eb != null) {
t = t + eb;
}
if(k == 0) {
t = t.replace("+","");
}
newList.add(k++,t);
}
return newList;
}
1.这次题目没对输入合法做出严格要求,只是对系数和指数不为0做出了要求。能进一步的对输入的信息做出更好的判定。
2.题目的测试点应该全部通过。
三次题目级的圈复杂度都过高,最高的甚至达到了23,下次应该尽量降低圈复杂度。
基本概念
圈复杂度(Cyclomatic complexity)是一种代码复杂度的衡量标准,是一种固定的数据模型计算方式。
圈复杂度用来衡量一个模块判定结构的复杂程度,数量上表现为线性无关路径条数,即覆盖所有的可能情况
最少使用的测试用例数。
圈复杂度大说明程序代码的判断逻辑复杂,可能质量低且难以测试和维护。
圈复杂度 | 代码状况 | 可测性 | 维护成本 |
---|---|---|---|
1~10 | 清晰、结构化 | 高 | 低 |
10~20 | 复杂 | 中 | 中 |
20~30 | 非常复杂 | 低 | 高 |
>30 | 不可读 | 不可测 | 非常高 |
所有代码的圈复杂度都应该降到10以下,参考网上的学习资料降低圈复杂度。
用List类创建字符串数组,增加并访问。
代码如下:
List<String> list = new ArrayList<String>();
int count = 10;
for(int i = 0;i < count;i++){
int t = input.nextInt();
list.add(t);
}
Iterator<String> itr = list.iterator();
while(itr.hasNext()){
String t = itr.next();
System.out.println(t);
}
正则表达式能够用来,匹配、查找、提取、替换。能够对字符串进行更多细节上的操作。
对比String类和Matcher类中的关于匹配的方法
//String类
public int indexOf(ch)
public int indexOf(s)
public int lastIndexOf(ch)
//只能进行特定的匹配,而且不能提取匹配的子字符串
//Matcher类
public boolean find()
public String group()
public String replaceAll(String replacement)
//能查找符合类型的字符串,并将它提取出来或者进行替换操作
Pattern类和Matcher类
结合使用,来对字符串进行操作。
public List<String> distill1() {
List<String> list = new ArrayList<String>();
String regexx = "[\\+\\-]?([1-9]\\d*\\*)?[x]([\\^][\\-\\+]?\\d*)?";
Pattern p1 = Pattern.compile(regexx);
Matcher m1 = p1.matcher(inStr);
while(m1.find()) {
list.add(m1.group());
}
return list;
}
1.功能实现不完整。对多项式求导还有待改进,没能完全实现多项式求导功能
2.圈复杂度无法控制。在控制圈复杂度上还有待改进,三次题目集的圈复杂度都没在10以下,在降低圈复杂的方面还有待研究,了解圈复杂度过高的原因,如何在设计之初就降低圈复杂度,尽量不要在实现完功能后,在去修改圈复杂度
3.思维僵化,死板。在写题目过程中,不能灵活的调用知识,即使掌握了新知识点,仍然沿用以前的思维考虑题目
4.查错能力低。不能系统的思考问题产生的原因,思考如何解决问题,而是不断地运行程序,不断地进行输入操作
5.阅读题目不仔细。在没能完全理解题目要求的情况下,就开始思考如何解决题目,一味的求快,在最后需要花费更多的时间来查错
原文:https://www.cnblogs.com/renwoxinga/p/14615079.html