一.前言
题集一主要考察的是Java的基本语法,主要包括输入输出,选择(if-else)循环(while,for)结构,数组的使用,字符串的操作,基本数据类型(int,double,char,boolean)第十题难度较高,其余题难度一般,题量较大。
题集二主要考察基本数据类型(int,double,char,boolean),数组,字符串的操作,方法的调用,以及一些Java自带的类方法的使用方法,其中,日期类算法考察了我们编程的逻辑性以及对日期中存在的特殊情况的处理,总体而言难度一般,题量较大,是对第一次作业的延伸。
题集三开始接触面向对象,主要考察类的基本用法以及创建对象,比如无参和有参的构造方法,属性的set和个体方法,可见性(public)和私有性(private),对类的设计是本次作业的重点,拥有一个设计良好的类,不仅能让代码简洁明了,减少冗杂的变量名,而且能减少错误的出现,让程序更稳定且易于修改。前三道题难度一般,最后一题难度较大,题量较少。
第一次作业和第二次作业没有花费我多长时间,差不多就是一天,几乎都不需要设计,很多题目都是一遍过,测试数据也测试的较少。第三次作业花费了我大量时间,又要设计又要测试,测试时测试了许多数据,还经常出错,让我做的非常痛苦。
二.设计与分析
1.GPS数据处理(第一次作业)
这个题目巨长,就像老太太裹脚布,又臭又长,其实题目很简单,就是给你一个字符串,按照,
把他们分隔开,然后验证每个字符的异或的十六进制是不是正和星号后的数字一样,并且字段二是A。正确的输出时间字段就OK。程序可能会读到很多条有效的语句,但是输出最后一条有效语句。这题主要检验字符串的一些操作,很多要用到的一些操作也都在题目里面告诉你了,关键就要看懂题目,但我在做这一题的时候,根本静不下心来看题目,让我误以为题目很难,这道题我是放在最后做的,具体代码如下
1 import java.util.Scanner; 2 public class Main 3 { 4 public static void main(String[] args) 5 { 6 Scanner input=new Scanner(System.in); 7 int hour=0,minute=0,second=0; 8 String str=input.nextLine(); 9 while(!str.equals("END")) 10 { 11 int index=str.indexOf(","); 12 index=str.indexOf(",",index+1); 13 if(str.substring(0,6).compareTo("$GPRMC")==0&&str.charAt(index+1)=='A') 14 { 15 int check1=str.charAt(1); 16 for(int i=2;str.charAt(i)!='*';i++) 17 { 18 check1^=str.charAt(i); 19 } 20 check1%=65536; 21 int num=Integer.parseInt(str.substring(str.length()-2,str.length()),16); 22 if(check1==num) 23 { 24 hour=(str.charAt(7)-'0')*10+(str.charAt(8)-'0'); 25 minute=(str.charAt(9)-'0')*10+(str.charAt(10)-'0'); 26 second=(str.charAt(11)-'0')*10+(str.charAt(12)-'0'); 27 hour=(hour+8)%24; 28 } 29 } 30 str=input.nextLine(); 31 } 32 if(hour<10) 33 System.out.print(0); 34 System.out.print(hour+":"); 35 if(minute<10) 36 System.out.print(0); 37 System.out.print(minute+":"); 38 if(second<0) 39 System.out.print(0); 40 System.out.print(second); 41 } 42 }View Code
2.有重复的数据
在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,输出“YES
”这三个字母;如果没有,则输出“NO
”。
这个题目要做的话有很多种方法可以做出来结果,但是很难做到满分,方法有和多种,但大多都超时或超限的,到作业截至我都没拿满分,这个是我之前改进方法的截图,只拿了一分,越改越垃圾,我那四分的代码如下
1 import java.util.Scanner; 2 public class Main{ 3 public static void main(String[] args){ 4 Scanner input = new Scanner(System.in); 5 int n=input.nextInt(); 6 int[] a=new int[n]; 7 int i,j; 8 int flag=0; 9 for(i=0;i<n;i++) 10 { 11 a[i]=input.nextInt(); 12 } 13 for(i=0;i<n;i++) 14 { 15 for(j=i+1;j<n-i-1;j++) 16 { 17 if(a[i]==a[j]) 18 { 19 flag=1; 20 break; 21 } 22 } 23 24 if(flag==1) 25 { 26 System.out.println("yes"); 27 break; 28 } 29 } 30 if(flag==0) 31 System.out.println("no"); 32 } 33 }View Code
输入格式:
你的程序首先会读到一个正整数n,n∈[1,100000],然后是n个整数。
3.判断三角形类型(第二次作业)
在做这个题目时,我的想法一开始是在数据能构成三角形的情况下,将等腰和直角分为两种情况,在在里面判断是否为等边三角形或等腰直角三角形,但后来发现这样很累赘,完全可以将判断等腰直角三角型放到第一种情况里去,这样最后就只需判断是否是直角三角形了和普通三角形了。写代码时只设计了一个主函数和一个主类,这个题目还有一点要注意的地方就是浮点数没有准确值,要有一定的误差区间,否则会判断错误。具体代码如下
1 import java.util.Scanner; 2 public class Main { 3 4 public static void main(String[] args) { 5 // TODO 自动生成的方法存根 6 Scanner input=new Scanner(System.in); 7 double a=input.nextDouble(); 8 double b=input.nextDouble(); 9 double c=input.nextDouble(); 10 if(a<1||a>200||b<1||b>200||c<1||c>200){ 11 System.out.print("Wrong Format"); 12 return ; 13 } 14 else if(a+b<=c||a+c<=b||b+c<=a){ 15 System.out.println("Not a triangle"); 16 return ; 17 } 18 else { 19 if(a==b||a==c||b==c){ 20 if(a==b&&a==c) 21 System.out.println("Equilateral triangle"); 22 else if(a*a+b*b<c*c+0.000001||a*a+b*b>c*c-0.000001||b*b+c*c<a*a+0.000001||b*b+c*c>a*a-0.000001||a*a+c*c<b*b+0.000001||a*a+c*c>b*b+0.000001) 23 System.out.println("Isosceles right-angled triangle"); 24 else 25 System.out.println("Isosceles triangle"); 26 } 27 else if(a*a+b*b<c*c+0.000001||a*a+b*b>c*c-0.000001||b*b+c*c<a*a+0.000001||b*b+c*c>a*a-0.000001||a*a+c*c<b*b+0.000001||a*a+c*c>b*b+0.000001){ 28 System.out.println("Right-angled triangle"); 29 } 30 else 31 System.out.println("General triangle"); 32 } 33 } 34 35 }View Code
4.定义日期类(第三次作业)
在做这个题目时,选择创建一个日期类,类中包含年月日的setter和getter方法,对象的有参和无参构造方法,以及判断是否为闰年的方法和输入数据是否正确的方法。其中,方法求下一天是核心算法,在这个方法里面会调用判断是否是闰年以及输入数据是否正确的方法,之后在求下一天,判断下一天是否大于该月最大天数,若大于,则进行月数加1,之后再判断该月是否大于12月,若大于,则进行年数加1。做这道题目注意逻辑即可,难度不大。代码如下
1 import java.util.Scanner; 2 public class Main{ 3 public static void main(String[] args){ 4 Scanner input=new Scanner(System.in); 5 int year1=input.nextInt(); 6 int month1=input.nextInt(); 7 int day1=input.nextInt(); 8 Date date=new Date(); 9 date.setYear(year1); 10 date.setMonth(month1); 11 date.setDay(day1); 12 date.getNextDay(); 13 } 14 } 15 class Date{ 16 private int year; 17 private int month; 18 private int day; 19 private int[] mon_maxnum=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; 20 public Date(){ 21 22 } 23 public void Date(int year1,int month1,int day1){ 24 this.year=year1; 25 this.month=month1; 26 this.day=day1; 27 } 28 public void setYear(int year){ 29 this.year=year; 30 } 31 public void setMonth(int month){ 32 this.month=month; 33 } 34 public void setDay(int day){ 35 this.day=day; 36 } 37 public int getYear(){ 38 return year; 39 } 40 public int getMonth(){ 41 return month; 42 } 43 public int getDay(){ 44 return day; 45 } 46 public boolean isLeapYear(int year){ 47 boolean result=false; 48 if((year%4==0&&year%100!=0)||year%400==0) 49 result=true; 50 return result; 51 } 52 public boolean checkInputValidity(int year,int month,int day){ 53 boolean result=false; 54 if(year<1900||year>2000||month<1||month>12||day<1||day>31) 55 result=true; 56 return result; 57 } 58 public void getNextDay(){ 59 if(checkInputValidity(year,month,day)){ 60 System.out.print("Date Format is Wrong"); 61 return ; 62 } 63 else 64 { 65 if(month==2){ 66 if(isLeapYear(year)) 67 mon_maxnum[2]=29; 68 } 69 if(day>mon_maxnum[month]){ 70 System.out.print("Date Format is Wrong"); 71 return ; 72 } 73 day++; 74 if(day>mon_maxnum[month]){ 75 day=1; 76 month++; 77 if(month>12){ 78 month=1; 79 year++; 80 } 81 } 82 System.out.println("Next day is:"+year+"-"+month+"-"+day); 83 } 84 } 85 }View Code
在求下一天使用到三次 if 镶嵌结构,由图可以看到,在求下一天这个方法复杂度和深度较高,而且在判断数据是否合法时,有一部分写在了求下一天这个方法(如下3-10行),这是不应该的,判断数据输入是否正确应放在同一方法中,这是代码应该被优化的地方。不仅如此,代码注释比例极低,几乎没有,这也是我之后要注意的问题。
else { if(month==2){ if(isLeapYear(year)) mon_maxnum[2]=29; } if(day>mon_maxnum[month]){ System.out.print("Date Format is Wrong"); return ; } day++; if(day>mon_maxnum[month]){ day=1; month++; if(month>12){ month=1; year++; } } System.out.println("Next day is:"+year+"-"+month+"-"+day); }
5.日期类设计(第三次作业)
在做这个题目是把我人都给搞蒙了,在运行测试时发现求前n天和求后n天的算法都没有设计好,算出来的数据都不对。这次作业耗时长主要是因为算法设计没有做好,导致后面又重新去设计。在这次作业中,我沿袭了上次作业所犯的错误,判断输入数据是没有考虑完全,漏掉了一些情况,不过好在测试点都过了。在设计求下n天时,先判断n是否大于365,然后判断是否是闰年就行了,将天数减到365天以下,之后就是天数慢慢累加进行进位和上一题一样的处理方法。求前n天时也是一样,将天数减到365天以下后,在进行天数的递减,只不过这里的天数减到零之后是将其赋给前一个月的最大天数,具体操作与求前n天大致相同。
在做求两个日期之间的天数的方法之前,要先做两日期大小的比较以及判断两日期是否相等的方法,做完之后分两种类型去求两日期之间的天数。第一种情况是第一个日期大于第二个日期,,以第一个日期为参照,将问题转化为求该日期的前n天,设置变量来记录天数,直到两个日期相等,再终止循环,逻辑大致与求前n天一致。第二种情况是第一个日期小于第二个日期,同样以第一个日期为参照物,将问题转化为求该日期的后n天,设置变量来记录天数,直到两个日期相等,再终止循环,逻辑大致与求后n天一致。具体代码如下
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args) { 5 Scanner input = new Scanner(System.in); 6 int year = 0; 7 int month = 0; 8 int day = 0; 9 10 int choice = input.nextInt(); 11 12 if (choice == 1) { // test getNextNDays method 13 int m = 0; 14 year = Integer.parseInt(input.next()); 15 month = Integer.parseInt(input.next()); 16 day = Integer.parseInt(input.next()); 17 18 DateUtil date = new DateUtil(year, month, day); 19 20 if (!date.checkInputValidity()) { 21 System.out.println("Wrong Format"); 22 System.exit(0); 23 } 24 25 m = input.nextInt(); 26 27 if (m < 0) { 28 System.out.println("Wrong Format"); 29 System.exit(0); 30 } 31 32 System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:"); 33 System.out.println(date.getNextNDays(m).showDate()); 34 } else if (choice == 2) { // test getPreviousNDays method 35 int n = 0; 36 year = Integer.parseInt(input.next()); 37 month = Integer.parseInt(input.next()); 38 day = Integer.parseInt(input.next()); 39 40 DateUtil date = new DateUtil(year, month, day); 41 42 if (!date.checkInputValidity()) { 43 System.out.println("Wrong Format"); 44 System.exit(0); 45 } 46 47 n = input.nextInt(); 48 49 if (n < 0) { 50 System.out.println("Wrong Format"); 51 System.exit(0); 52 } 53 54 System.out.print( 55 date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:"); 56 System.out.println(date.getPreviousNDays(n).showDate()); 57 } else if (choice == 3) { //test getDaysofDates method 58 year = Integer.parseInt(input.next()); 59 month = Integer.parseInt(input.next()); 60 day = Integer.parseInt(input.next()); 61 62 int anotherYear = Integer.parseInt(input.next()); 63 int anotherMonth = Integer.parseInt(input.next()); 64 int anotherDay = Integer.parseInt(input.next()); 65 66 DateUtil fromDate = new DateUtil(year, month, day); 67 DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay); 68 69 if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { 70 System.out.println("The days between " + fromDate.showDate() + 71 " and " + toDate.showDate() + " are:" 72 + fromDate.getDaysofDates(toDate)); 73 } else { 74 System.out.println("Wrong Format"); 75 System.exit(0); 76 } 77 } 78 else{ 79 System.out.println("Wrong Format"); 80 System.exit(0); 81 } 82 } 83 } 84 class DateUtil{ 85 private int year; 86 private int month; 87 private int day; 88 private int[] mon_maxnum=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31,0}; 89 private int allDay=365; 90 public DateUtil(int year,int month,int day){ 91 this.year=year; 92 this.month=month; 93 this.day=day; 94 } 95 public DateUtil(DateUtil d){ 96 this.year = d.getYear(); 97 this.month = d.getMonth(); 98 this.day = d.getDay(); 99 } 100 public int getYear(){ 101 return year; 102 } 103 public int getMonth(){ 104 return month; 105 } 106 public int getDay(){ 107 return day; 108 } 109 public boolean checkInputValidity(){ 110 boolean result=true; 111 if(year<1820||year>2020||month<1||month>12||day<1||day>31) 112 result=false; 113 return result; 114 } 115 public boolean isLeapYear(int year){ 116 boolean result=false; 117 if((year%4==0&&year%100!=0)||year%400==0) 118 result=true; 119 return result; 120 } 121 public DateUtil getNextNDays(int n){ 122 while(n>365){ 123 if(this.month<=2){ 124 if(isLeapYear(this.year)){ 125 n=n-366; 126 this.year++; 127 } 128 else{ 129 n=n-365; 130 this.year++; 131 } 132 } 133 else if(this.month>2){ 134 if(isLeapYear(this.year+1)){ 135 n=n-366; 136 this.year++; 137 } 138 else{ 139 n=n-365; 140 this.year++; 141 } 142 } 143 } 144 for(int i=0;i<n;i++){ 145 this.day++; 146 if(isLeapYear(this.year)){ 147 mon_maxnum[2]=29; 148 } 149 if(this.day>mon_maxnum[this.month]){ 150 this.month++; 151 this.day=1; 152 if(this.month>12){ 153 this.year++; 154 this.month=1; 155 } 156 } 157 } 158 return this; 159 } 160 public String showDate(){ 161 String str=year+"-"+month+"-"+day; 162 return str; 163 } 164 public DateUtil getPreviousNDays(int n){ 165 while(n>365){ 166 if(this.month>2){ 167 if(isLeapYear(this.year)){ 168 this.year--; 169 n=n-366; 170 } 171 else{ 172 this.year--; 173 n=n-365; 174 } 175 } 176 else if(month<=2){ 177 if(isLeapYear(this.year-1)){ 178 this.year--; 179 n=n-366; 180 } 181 else{ 182 this.year--; 183 n=n-365; 184 } 185 } 186 } 187 for(int i=0;i<n;i++){ 188 this.day--; 189 if(this.day<=0){ 190 if(isLeapYear(this.year)){ 191 mon_maxnum[2]=29; 192 } 193 this.month--; 194 if(this.month<=0){ 195 this.year--; 196 this.month=12; 197 } 198 this.day=mon_maxnum[this.month]; 199 } 200 } 201 return this; 202 } 203 public boolean compareDates(DateUtil date){ 204 boolean result=false; 205 if(this.year>date.year) 206 result=true; 207 else if(this.year==date.year&&this.month>date.month) 208 result=true; 209 else if(this.year==date.year&&this.month==date.month&&this.day>date.day) 210 result=true; 211 return result; 212 } 213 public boolean equalTwoDates(DateUtil date){ 214 boolean result=true; 215 if(this.year!=date.year) 216 result=false; 217 else if(this.month!=date.month) 218 result=false; 219 else if(this.day!=date.day) 220 result=false; 221 return result; 222 } 223 public int getDaysofDates(DateUtil date){ 224 int gap=0; 225 if(this.compareDates(date)){ 226 while(this.year-date.year>=2){ 227 if(this.month>2){ 228 if(isLeapYear(this.year)){ 229 gap+=366; 230 } 231 else 232 gap+=365; 233 } 234 if(this.month<=2){ 235 if(isLeapYear(this.year-1)){ 236 gap+=366; 237 } 238 else 239 gap+=365; 240 } 241 this.year--; 242 } 243 while(true){ 244 if(this.equalTwoDates(date)){ 245 break; 246 } 247 gap++; 248 this.day--; 249 if(this.day<=0){ 250 this.month--; 251 if(this.month<=0){ 252 this.year--; 253 this.month=12; 254 } 255 if(isLeapYear(this.year)){ 256 mon_maxnum[2]=29; 257 } 258 else 259 mon_maxnum[2]=28; 260 this.day=mon_maxnum[this.month]; 261 } 262 } 263 } 264 else{ 265 while(date.year-this.year>=2){ 266 if(this.month>2){ 267 if(isLeapYear(this.year+1)){ 268 gap+=366; 269 } 270 else 271 gap+=365; 272 } 273 if(this.month<=2){ 274 if(isLeapYear(this.year)){ 275 gap+=366; 276 } 277 else 278 gap+=365; 279 } 280 this.year++; 281 } 282 while(true){ 283 if(this.equalTwoDates(date)){ 284 break; 285 } 286 gap++; 287 this.day++; 288 if(isLeapYear(this.year)){ 289 mon_maxnum[2]=29; 290 } 291 else 292 mon_maxnum[2]=28; 293 if(this.day>mon_maxnum[this.month]){ 294 this.month++; 295 this.day=1; 296 if(this.month>12){ 297 this.year++; 298 this.month=1; 299 } 300 301 } 302 } 303 } 304 return gap; 305 } 306 }View Code
由图可以看到(求下n天),(求前n天),(求两日期之间的天数)这三个方法复杂度以及深度都很高,里面都采用了两次循环结构以及三次 if 结构嵌套,由于自身知识受限,实在写不出啥高级的的东西。除此之外还有一个缺点就是代码注释比例非常低,几乎就没有。当然最要命的是我所设立的判断数据是否正确的方法不完善,而在后续的方法里也没有补充,这就导致了输入2020年2月30日这个数据不会报错,错误代码如下
public boolean checkInputValidity(){ boolean result=true; if(year<1820||year>2020||month<1||month>12||day<1||day>31) result=false; return result; }
这里应该再加一个判断输入日期是否大于该月最大天数才算是正确的方法,这是我在设计上的遗漏。
三.踩坑心得
1.浮点数没有精确值,再进行判断时要给出误差区间,具体体现在作业二判断三角形类型。
2.代码要有严密的逻辑,写代码之前要写做好设计,不能无脑下手写,靠碰钉子改错会浪费大量时间,做作业效率极低,具体体现在作业三最后一题。
3.在作业二房产税中,有些数据必需用float强制转换类型,原因是double的类型的精度更高,不然输出答案过不了。
4.测试代码是否正确时,要选用不同且大量有针对性的数据进行测试,不能只是过了测试点,只有这样才能保证自己的代码无误,具体体现在作业三最后一题。
5.代码运行速度过慢或内存超限,导致过不了测试点,不知道怎样将自己的代码优化(到目前为止还是不会),以至于现在还是拿不了满分,具体体现在第一次作业判断有重复数据。
四.总结
前两次的作业均未涉及到面向对象,做起题目来基本都是用c语言的思想在做,没有具体体会到面向对象的便捷操作。第三次的作业才运用到了对象,但因为前两次的作业均未涉及,课上理解的也不够通彻,第三次作业让我做的很痛苦,分数也没有拿的很高。在收获上,学习了Java的一些基本语法的操作,有些东西和c不一样,最明显的就是字符串和数组的操作,要比c方便很多。然后就是学到了一些面向对象的操作和编程思想,以对象为核心,方法属于每个对象,能否实现是每个对象说了算的。最后,就是要给代码写注释!!!这非常重要,不然几百行的代码让人看的很难受,以及书写和命名要规范,要养成良好的编写代码的习惯。总的来说,三次作业由浅及深,难度逐渐增加,但同时我也看到了自己所学实在是浅薄,对一些Java的基本操作和类的使用还是不熟悉,今后要加强自己的自学能力,好提高做作业的效率。
五。对课程的建议
希望老师有时间可以讲解一下pta上的部分作业,毕竟是自己做的,可以给我们加深一下印象。还有就是PTA上的练习希望要求不要太苛刻了,数据量庞大且抽象的题目不太适合我这种接受能力差一点的人练手,还是希望能多出一些基础的题目。也希望老师在讲授到重点的时候,适当放慢点速度,让我们有一个思考问题的时间,我上课的时候还在理解老师所讲的知识的时候,老师已经开始讲下一个部分了,刚刚接触java,难免有一些不熟练,希望老师能多给我们一些时间来思考完成问题。
标签:总结,int,题集,System,month,public,year,day From: https://www.cnblogs.com/BR-boru/p/17259631.html