题目集1~3的总结性Blog
目录
1、前言
2、设计与分析
3、踩坑心得
4、改进建议
5、总结
题目集1:
1、计算年利率
2、身体质量指数测算
3、九九乘法表(双循环)
4、快递运费
5、去掉重复字符
6、统计一个子串在整串中出现的次数
7、有重复数据
8、从一个字符串中移除包含在另一个字符串中的字符
9、Prime Numbers
10、GPS数据处理
11、求定积分
12、列出最简真分数序列*
题目集2
1、长度质量计算单位换算
2、奇数求和
3、房产税计算2022
4、游戏角色选择
5、学号识别
6、巴比伦法求平方根近似值
7、二进制数值提取
8、判断三角形类型
9、求下一天
题目集3
1、创建圆类型
2、创建账户类Account
3、定义日期类
4、日期类设计
这是我第一次用Java写代码,因为完全不懂Java编译环境,因此在写题目集1时闹出了许多的笑话例如不知道主类命名为Main等等,在网上查了很久才解决这个问题。
在写题目集1时让我印象最深刻的是Java里面有很多类可以用,有很多现成的方法可以使用,特别是字符串操作的题目,这点让我印象尤为深刻。虽然字符串操作的题目一直都是我的弱项,但是在Java里成堆的字符串操作方法的帮助下,我还是很快速的解决了题目集1。
题目集2大多数的题目都不难,不过有些题目例如求三角形类型和求下一天这两道题时,有两个测试点困扰了我许久,具体原因在设计与分析。
题目集3第一次使用到了类,并且的最后一题是题目集2的迭代,虽然我在写题目集2的最后一题时,算法设计十分复杂,但是在我写完题目集2的最后一题之后,我和同学就题目集2的最后一题的解决方法交换了意见,在那时我才知道我的算法是多么地复杂。因此,在写题目集3最后一题时,我将我的算法加以改进,虽然中途遇到了一些困难,但是好在有同学的帮助,也算是顺利地完成了题目集3。
题目集1的第十题应该是题目集1里面比较难的题了,可是如果理解了题意,这题还是比较好做的,本质上还是字符串的操作要熟练,其中出现了异或运算符^,实际上就是不进位的相加,例如:
1 1011011 ^ 1001010 = 0010001
题干中还有一个隐藏的信息,就是校验信息之后需要我们输出的是北京时间。因此,在校验无误之后,我们算出的时间还需要加8个小时,这也就涉及到了时间计算的操作。本题具体源码如下:
1 import java.util.*; 2 3 public class Main{ 4 public static void main(String[] args){ 5 String a,b; 6 int i,x,y = 0,h,m,s,flag = 0,z; 7 Scanner input = new Scanner(System.in); 8 a = input.nextLine(); 9 b = input.nextLine(); 10 String[] frag = a.split(","); 11 if (frag[0].equals("$GPRMC")){ 12 x=a.indexOf("*"); 13 for (i = 1;i <= x - 1;i++){ 14 y = y^a.charAt(i); 15 } 16 y = y%65536; 17 if ((frag[2].equals("A")) && (y == Integer.parseInt(a.substring(x+1),16))){ 18 flag = 1; 19 } 20 } 21 if (flag == 1){ 22 h = (Integer.parseInt(frag[1].substring(0,2),10)+8)%24; 23 m = Integer.parseInt(frag[1].substring(2,4),10); 24 s = Integer.parseInt(frag[1].substring(4,6),10); 25 if (h < 10){ 26 System.out.printf("0%d:%d:%d",h,m,s); 27 }else{ 28 System.out.printf("%d:%d:%d",h,m,s); 29 } 30 } 31 } 32 }
题目集2是要我们判断三角形的类型,第一眼看到这道题我还以为也是凑数的,因为类似的题的写c语言的时候已经写过好多遍了,算法也非常的简单,无非就是要注意一下判断顺序就行了,万万没想到的是,就是这题的一个等腰三角形的测试点,可以卡我两天!!!最后解决的过程也是非常的有趣,我直接在我高中的班群里问了这个问题,没想到一个物理系的同学给了我答案。具体聊天记录如下:
所以遇到问题了,还是不要埋头苦干,和同学、老师们多多交流真的可以解决很多问题。题目集2第八题具体代码如下:
import java.util.*; public class Main{ public static void main(String[] args){ Scanner input=new Scanner(System.in); float a,b,c; a=input.nextFloat(); b=input.nextFloat(); c=input.nextFloat(); if (a >= 1 && a <= 200 && b >= 1 && b <= 200 && c >= 1 && c <= 200){ if (a + b <= c || a + c <= b || b + c <= a){ System.out.printf("Not a triangle"); } else if (a == b && b == c){ System.out.printf("Equilateral triangle"); } else if ((a == b && Math.abs(a * a + b * b - c * c) < 0.000001) || (b == c && Math.abs(b * b + c * c - a * a) < 0.000001) || (a == c && Math.abs(a * a + c * c - b * b) < 0.000001)){ System.out.printf("Isosceles right-angled triangle"); } else if (a == b || a == c || b == c){ System.out.printf("Isosceles triangle"); } else if (((a * a + b * b) == c * c) || ((b * b + c * c) == a * a) || ((a * a + c * c) == b * b)){ System.out.printf("Right-angled triangle"); } else{ System.out.printf("General triangle"); } } else{ System.out.printf("Wrong Format"); } } }
至于第九题其实对现在的我来说是已经没什么问题了,但是对刚刚碰到这题的我来说,解这道题的过程真的很痛苦。
算法设计我选择了最笨的办法,一个月一个月的判断,一天一天地加,没有定义任何数组,导致最后写出来的代码超过了限制长度,因此改起来也非常的麻烦。源码就放在下面了,我自己都没眼看。
1 import java.util.*; 2 public class Main{ 3 public static void main(String[] args){ 4 Scanner input=new Scanner(System.in); 5 int year,month,day;; 6 year=input.nextInt(); 7 month=input.nextInt();; 8 day=input.nextInt(); 9 nextDate(year,month,day);} 10 public static boolean isLeapYear(int year){ 11 if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)){ 12 return true; 13 }else{ 14 return false; 15 } 16 } 17 public static boolean checkInputValidity(int year,int month,int day){ 18 if ((year >= 1820 && year <= 2020) && (month >= 1 && month <= 120) && (day >= 1 && day <= 31)){ 19 return true; 20 }else{ 21 return false; 22 } 23 } 24 public static void nextDate(int year,int month,int day){ 25 int flag = 0,x = 0; 26 if (checkInputValidity(year,month,day)){ 27 if (isLeapYear(year)){ 28 if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 && flag == 0){ 29 if (day <= 30){ 30 day = day + 1;x = 1; 31 }else if (day == 31){ 32 day = 1; 33 month = month + 1; 34 flag = 1;x = 1; 35 } 36 } else if (month == 2 && flag == 0){ 37 if (day <= 28){ 38 day = day + 1;x = 1; 39 } else if (day == 29){ 40 day = 1; 41 month = month + 1; 42 flag = 1;x = 1;} 43 }else{ 44 if (day <= 29){ 45 day = day + 1;x = 1; 46 }else if (day == 30){ 47 day = 1; 48 month = month + 1; 49 flag = 1;x = 1; 50 } 51 } 52 }else{ 53 if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 && flag == 0){ 54 if (day <= 30){ 55 day = day + 1;x = 1; 56 }else if (day == 31){ 57 day = 1; 58 month = month + 1; 59 flag = 1;x = 1; 60 } 61 } 62 else if (month == 2 && flag == 0){ 63 if (day <= 27){ 64 day = day + 1;x = 1; 65 } else if(day == 28){ 66 day = 1; 67 month = month + 1; 68 flag = 1;x = 1; 69 } 70 } else{ 71 if (day <= 29){ 72 day = day + 1;x = 1;}else if (day == 30){ 73 day = 1; 74 month = month + 1; 75 flag = 1;x = 1; 76 } 77 } 78 } 79 if (month == 13){ 80 month = 1; 81 year = year + 1;x = 1; 82 } 83 if (year == 2021){ 84 x = 0; 85 } 86 if (x == 1){ 87 System.out.println("Next date is:"+year+"-"+month+"-"+day);return ;} 88 } 89 System.out.printf("Wrong Format"); 90 } 91 }
我自己所有的测试点都通过之后,也想看看别人是怎么做这道题的,所以我问了我们班写代码能力比较好的同学,想要看看人家的方法是什么,我能不能学一学。后面这位同学说他的代码只写了50多行,定义了一个月份的数组,并且将他的想法也告诉了我,那个时候我才知道我写的是有多复杂,要是我早点和别人交流就好了。现在回想一下,我能一条路走到黑也真是个天才。
题目集三前两道题都比较简单这里就不多解释了,题目集最后两题都是关于日期类的编写,由于有了前车之鉴,我也对我的算法进行了改良。
本题因为吸取了上一次的经验,这里对我的算法进行了优化,并且牵扯到的类的关系也比较简单,以下是本题的类图和代码:
1
1 import java.util.*; 2 public class Main{ 3 public static void main(String[] args){ 4 Scanner input = new Scanner(System.in); 5 int year,month,day; 6 year=input.nextInt(); 7 month=input.nextInt(); 8 day=input.nextInt(); 9 Date date = new Date(year,month,day); 10 if (!date.checkInputValidity()){ 11 System.out.printf("Date Format is Wrong"); 12 return; 13 } 14 date.getNextDate(); 15 if (date.checkInputValidity()){ 16 System.out.printf("Next day is:%d-%d-%d",date.getYear(),date.getMonth(),date.getDay()); 17 } 18 else{ 19 System.out.printf("Date Format is Wrong"); 20 } 21 } 22 } 23 class Date{ 24 private int year; 25 private int month; 26 private int day; 27 public int[] mon_maxnum = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; 28 public Date(){ 29 30 } 31 32 public Date(int year,int month,int day){ 33 this.year = year; 34 this.month = month; 35 this.day = day; 36 } 37 public int getYear(){ 38 return this.year; 39 } 40 41 public void setYear(int year){ 42 this.year=year; 43 } 44 45 public int getMonth(){ 46 return this.month; 47 } 48 49 public void setMonth(int month){ 50 this.month=month; 51 } 52 53 public int getDay(){ 54 return this.day; 55 } 56 57 public void setDay(int day){ 58 this.day=day; 59 } 60 61 public boolean isLeapYear(int year){ 62 if ((this.year % 4 == 0 && this.year % 100 != 0) || (year % 400 == 0)){ 63 return true; 64 } else{ 65 return false; 66 } 67 } 68 69 public boolean checkInputValidity(){ 70 if (isLeapYear(this.year)){ 71 mon_maxnum[2] = 29; 72 } 73 if ((this.year >= 1900 && this.year <= 2000) && (this.month >= 1 && this.month <= 12) && (this.day >= 1 && this.day <= mon_maxnum[this.month])){ 74 return true; 75 } else{ 76 return false; 77 } 78 } 79 public void getNextDate(){ 80 if (isLeapYear(this.year)){ 81 mon_maxnum[2] = 29; 82 } 83 if (this.day + 1 > mon_maxnum[this.month]){ 84 this.day = 1; 85 if (this.month < 12){ 86 this.month++; 87 } else{ 88 this.month = 1; 89 this.year++; 90 } 91 } else{ 92 this.day++; 93 } 94 } 95 }
这里现附上本题的类图:
可以看到,本题和上一题在类图中的区别就是多了几个方法,但这几个方法是这道题目的灵魂。先说两天之差的解题思路,方法源码如下:
1 public int getDaysofDates(DateUtil date) { 2 int substract = 0, flag = 0;//i为年份j为月份k为日 3 if (this.year<=date.getYear()) { 4 int i = this.year, j = this.month, k = this.day;//i为年份j为月份k为日 5 for (; i <= date.getYear(); ) { 6 if (isLeapYear(i)) { 7 mon_maxnum[2] = 29; 8 } else { 9 mon_maxnum[2] = 28; 10 } 11 if (i == date.getYear()) { 12 for (; j <= date.getMonth(); ) { 13 if ((i == date.getYear()) && (j == date.getMonth())) { 14 if (isLeapYear(i)) { 15 mon_maxnum[2] = 29; 16 } else { 17 mon_maxnum[2] = 28; 18 } 19 substract = substract + date.getDay() - k; 20 break; 21 } else { 22 substract = substract + mon_maxnum[j]; 23 j++; 24 } 25 } 26 break; 27 } else { 28 if (isLeapYear(i)) { 29 mon_maxnum[2] = 29; 30 } else { 31 mon_maxnum[2] = 28; 32 } 33 if (j < 12) { 34 substract += mon_maxnum[j]; 35 j++; 36 } else { 37 substract += 31; 38 i++; 39 j = 1; 40 } 41 } 42 } 43 } else { 44 int i = date.getYear(), j = date.getMonth(), k = date.getDay();//i为年份j为月份k为日 45 for (; i <= this.year; ) { 46 if (i == this.year) { 47 if (isLeapYear(i)) { 48 mon_maxnum[2] = 29; 49 } else { 50 mon_maxnum[2] = 28; 51 } 52 for (; j <= this.month; ) { 53 if (i == this.year && j == this.month) { 54 substract = substract + this.day - k; 55 flag = 1; 56 break; 57 } 58 substract = substract + mon_maxnum[j]; 59 j++; 60 } 61 flag = 1; 62 } 63 if (flag == 1) { 64 break; 65 } else { 66 if (j < 12) { 67 if (isLeapYear(i)) { 68 mon_maxnum[2] = 29; 69 } else { 70 mon_maxnum[2] = 28; 71 } 72 substract += mon_maxnum[j]; 73 j++; 74 } else { 75 substract += 31; 76 i++; 77 j = 1; 78 } 79 } 80 } 81 } 82 return substract; 83 }
不难看出我这里分了两种情况,一种为前一个日期大于后一个日期,另一种为前一个日期小于后一个日期。为什么要这样分呢?
因为在我的算法中,不管是月还是日都是慢慢增加,直到某个值时重新赋值为1,致使年份+1,从而必定会有一个日期是增加的,因此增加的一定是日期较小的那个日期,所以我在这里分了两种情况进行讨论。这里还有一个细节,就是当我的类里面的属性需要改变时,我是将类里面的属性赋给了i、j、k,因为在我看来,类里面的属性经过setter方法赋值之后是不能改变的,应该用其他变量来接收里面的值再加以使用。因为如果我们改变了属性的值的话,第一次调用对象的类的方法可能可以得到正确答案,但是下一次调用时,由于对象指向的类里面的属性在经过第一次调用之后已经发生了改变,因此使得我们得不到想要的结果。
由于获得前N天的日期和后N天的日期做法类似,因此我会放出两个方法的源码,但是只解释求后N天的代码。
1 public DateUtil getNextNDays (int n){ 2 DateUtil Date = new DateUtil(this.year, this.month, this.day); 3 for (; n > 0; ) { 4 if (isLeapYear(Date.getYear())) { 5 mon_maxnum[2] = 29; 6 } else { 7 mon_maxnum[2] = 28; 8 } 9 if (Date.getDay() < mon_maxnum[Date.getMonth()]) { 10 Date.setDay(Date.getDay() + 1); 11 n--; 12 } else { 13 if (Date.getMonth() < 12) { 14 Date.setMonth(Date.getMonth() + 1); 15 Date.setDay(1); 16 n--; 17 } else { 18 Date.setMonth(1); 19 Date.setDay(1); 20 Date.setYear(Date.getYear() + 1); 21 n--; 22 } 23 } 24 } 25 return Date; 26 } 27 28 public DateUtil getPreviousNDays ( int n){ 29 DateUtil Date = new DateUtil(this.year, this.month, this.day); 30 for (; n > 0; ) { 31 if (isLeapYear(Date.getYear())) { 32 mon_maxnum[2] = 29; 33 } else { 34 mon_maxnum[2] = 28; 35 } 36 if (Date.getDay() > 1) { 37 Date.setDay(Date.getDay() - 1); 38 n--; 39 } else { 40 if (Date.getMonth() > 1) { 41 Date.setMonth(Date.getMonth() - 1); 42 Date.setDay(mon_maxnum[Date.getMonth()]); 43 n--; 44 } else { 45 Date.setYear(Date.getYear() - 1); 46 Date.setMonth(12); 47 Date.setDay(31); 48 n--; 49 } 50 } 51 } 52 return Date; 53 }
这题和求下一天的算法基本类似,只不过是把1改成了n,但是里面有一个非常有意思的测试点,就是int最大值,因此n的值一定不能与任何正数相加,不然就超过了int的最大值,就这个测试点而言,不下于三位同学找我说遇到了这个问题,然后我看他们的代码,都是有n加某个正数的代码,导致这个测试点过不去。
以下是本题的源码:
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 year = 0; 6 int month = 0; 7 int day = 0; 8 9 int choice = input.nextInt(); 10 11 if (choice == 1) { // test getNextNDays method 12 int m = 0; 13 year = Integer.parseInt(input.next()); 14 month = Integer.parseInt(input.next()); 15 day = Integer.parseInt(input.next()); 16 17 DateUtil date = new DateUtil(year, month, day); 18 19 if (!date.checkInputValidity()) { 20 System.out.println("Wrong Format"); 21 System.exit(0); 22 } 23 24 m = input.nextInt(); 25 26 if (m < 0) { 27 System.out.println("Wrong Format"); 28 System.exit(0); 29 } 30 31 System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:"); 32 System.out.println(date.getNextNDays(m).showDate()); 33 } else if (choice == 2) { // test getPreviousNDays method 34 int n = 0; 35 year = Integer.parseInt(input.next()); 36 month = Integer.parseInt(input.next()); 37 day = Integer.parseInt(input.next()); 38 39 DateUtil date = new DateUtil(year, month, day); 40 41 if (!date.checkInputValidity()) { 42 System.out.println("Wrong Format"); 43 System.exit(0); 44 } 45 46 n = input.nextInt(); 47 48 if (n < 0) { 49 System.out.println("Wrong Format"); 50 System.exit(0); 51 } 52 53 System.out.print( 54 date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:"); 55 System.out.println(date.getPreviousNDays(n).showDate()); 56 } else if (choice == 3) { //test getDaysofDates method 57 year = Integer.parseInt(input.next()); 58 month = Integer.parseInt(input.next()); 59 day = Integer.parseInt(input.next()); 60 61 int anotherYear = Integer.parseInt(input.next()); 62 int anotherMonth = Integer.parseInt(input.next()); 63 int anotherDay = Integer.parseInt(input.next()); 64 65 DateUtil fromDate = new DateUtil(year, month, day); 66 DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay); 67 68 if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { 69 System.out.println("The days between " + fromDate.showDate() + 70 " and " + toDate.showDate() + " are:" 71 + fromDate.getDaysofDates(toDate)); 72 } else { 73 System.out.println("Wrong Format"); 74 System.exit(0); 75 } 76 } 77 else{ 78 System.out.println("Wrong Format"); 79 System.exit(0); 80 } 81 } 82 } 83 class DateUtil { 84 private int year; 85 private int month; 86 private int day; 87 public int[] mon_maxnum = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 88 89 public DateUtil() { 90 91 } 92 93 public DateUtil(int year, int month, int day) { 94 this.year = year; 95 this.month = month; 96 this.day = day; 97 } 98 99 public int getYear() { 100 return this.year; 101 } 102 103 public void setYear(int year) { 104 this.year = year; 105 } 106 107 public int getMonth() { 108 return this.month; 109 } 110 111 public void setMonth(int month) { 112 this.month = month; 113 } 114 115 public int getDay() { 116 return this.day; 117 } 118 119 public void setDay(int day) { 120 this.day = day; 121 } 122 123 public boolean isLeapYear(int year) { 124 if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) { 125 return true; 126 } else { 127 return false; 128 } 129 } 130 131 public boolean checkInputValidity() { 132 if (isLeapYear(this.year)) { 133 mon_maxnum[2] = 29; 134 } 135 if ((this.year >= 1820 && this.year <= 2020) && (this.month >= 1 && this.month <= 12) && (this.day >= 1 && this.day <= mon_maxnum[this.month])) { 136 return true; 137 } else { 138 return false; 139 } 140 } 141 142 public boolean compareDates(DateUtil date) { 143 if (this.year < date.getYear()) { 144 return true; 145 } else if (this.month < date.getMonth()) { 146 return true; 147 } else if (this.day > date.getDay()) { 148 return true; 149 } else { 150 return false; 151 } 152 } 153 154 public boolean equalTwoDates(DateUtil date) { 155 if ((this.year == date.getYear()) && (this.month == date.getMonth()) && (this.day == date.getDay())) { 156 return true; 157 } else { 158 return false; 159 } 160 } 161 162 public int getDaysofDates(DateUtil date) { 163 int substract = 0, flag = 0;//i为年份j为月份k为日 164 if (this.year<=date.getYear()) { 165 int i = this.year, j = this.month, k = this.day;//i为年份j为月份k为日 166 for (; i <= date.getYear(); ) { 167 if (isLeapYear(i)) { 168 mon_maxnum[2] = 29; 169 } else { 170 mon_maxnum[2] = 28; 171 } 172 if (i == date.getYear()) { 173 for (; j <= date.getMonth(); ) { 174 if ((i == date.getYear()) && (j == date.getMonth())) { 175 if (isLeapYear(i)) { 176 mon_maxnum[2] = 29; 177 } else { 178 mon_maxnum[2] = 28; 179 } 180 substract = substract + date.getDay() - k; 181 break; 182 } else { 183 substract = substract + mon_maxnum[j]; 184 j++; 185 } 186 } 187 break; 188 } else { 189 if (isLeapYear(i)) { 190 mon_maxnum[2] = 29; 191 } else { 192 mon_maxnum[2] = 28; 193 } 194 if (j < 12) { 195 substract += mon_maxnum[j]; 196 j++; 197 } else { 198 substract += 31; 199 i++; 200 j = 1; 201 } 202 } 203 } 204 } else { 205 int i = date.getYear(), j = date.getMonth(), k = date.getDay();//i为年份j为月份k为日 206 for (; i <= this.year; ) { 207 if (i == this.year) { 208 if (isLeapYear(i)) { 209 mon_maxnum[2] = 29; 210 } else { 211 mon_maxnum[2] = 28; 212 } 213 for (; j <= this.month; ) { 214 if (i == this.year && j == this.month) { 215 substract = substract + this.day - k; 216 flag = 1; 217 break; 218 } 219 substract = substract + mon_maxnum[j]; 220 j++; 221 } 222 flag = 1; 223 } 224 if (flag == 1) { 225 break; 226 } else { 227 if (j < 12) { 228 if (isLeapYear(i)) { 229 mon_maxnum[2] = 29; 230 } else { 231 mon_maxnum[2] = 28; 232 } 233 substract += mon_maxnum[j]; 234 j++; 235 } else { 236 substract += 31; 237 i++; 238 j = 1; 239 } 240 } 241 } 242 } 243 return substract; 244 } 245 public String showDate (){ 246 return this.year+"-"+this.month+"-"+this.day; 247 } 248 public DateUtil getNextNDays (int n){ 249 DateUtil Date = new DateUtil(this.year, this.month, this.day); 250 for (; n > 0; ) { 251 if (isLeapYear(Date.getYear())) { 252 mon_maxnum[2] = 29; 253 } else { 254 mon_maxnum[2] = 28; 255 } 256 if (Date.getDay() < mon_maxnum[Date.getMonth()]) { 257 Date.setDay(Date.getDay() + 1); 258 n--; 259 } else { 260 if (Date.getMonth() < 12) { 261 Date.setMonth(Date.getMonth() + 1); 262 Date.setDay(1); 263 n--; 264 } else { 265 Date.setMonth(1); 266 Date.setDay(1); 267 Date.setYear(Date.getYear() + 1); 268 n--; 269 } 270 } 271 } 272 return Date; 273 } 274 275 public DateUtil getPreviousNDays ( int n){ 276 DateUtil Date = new DateUtil(this.year, this.month, this.day); 277 for (; n > 0; ) { 278 if (isLeapYear(Date.getYear())) { 279 mon_maxnum[2] = 29; 280 } else { 281 mon_maxnum[2] = 28; 282 } 283 if (Date.getDay() > 1) { 284 Date.setDay(Date.getDay() - 1); 285 n--; 286 } else { 287 if (Date.getMonth() > 1) { 288 Date.setMonth(Date.getMonth() - 1); 289 Date.setDay(mon_maxnum[Date.getMonth()]); 290 n--; 291 } else { 292 Date.setYear(Date.getYear() - 1); 293 Date.setMonth(12); 294 Date.setDay(31); 295 n--; 296 } 297 } 298 } 299 return Date; 300 } 301 }
这三次作业踩坑最严重的就是判断三角形类型和求下一天了,在设计与分析里面也是重点提到了里面的问题的,但是还有一个小问题,关于我第一次写代码碰到了内存超限和运行超时的问题。第一次碰到这个问题是在题目集1的第七题有重复数据,以下是这个题目的描述:
在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。 你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,输出“YES”这三个字母;如果没有,则输出“NO”。 输入格式: 你的程序首先会读到一个正整数n,n∈[1,100000],然后是n个整数。 输出格式: 如果这些整数中存在重复的,就输出: YES 否则,就输出: NO 输入样例: 5 1 2 3 1 4 输出样例: YES
可以看到,这题的n最大可以取到100000,所以用两层循环必定会超时,当时就这一个点让我卡了好久,后面我还去网上查了快速排序的编写方法,可是写到后面还是会有问题,因为快速排序的O不够稳定。所以我就打开排名向已经完成这道题目的同学请教,后面才知道,原来Java里面的Arrays类里面还有一个叫sort的方法,都有这么简便的方法了,我还手搓干什么啊!!!而且我自己写的还有问题!!!别人写好的方法肯定比我的好用嘛!由于这是我第一次写小结,双重循环和手搓快排的源码已经找不到了,以下是我踩坑之后改进的源码:
1 public class Main { 2 public static void main(String[] args) { 3 int n, i, t, j, flag = 0; 4 Scanner input = new Scanner(System.in); 5 n = input.nextInt(); 6 int[] a = new int[n]; 7 for (i = 0; i <= n - 1; i++) { 8 a[i] = input.nextInt(); 9 } 10 Arrays.sort(a); 11 if (n>1){ 12 for (i = 0; i <= n - 2; i++) { 13 if (a[i] == a[i + 1]) { 14 flag = 1; 15 break; 16 } 17 } 18 } 19 if (flag == 1) { 20 System.out.printf("YES"); 21 }else{ 22 System.out.printf("NO"); 23 } 24 } 25 }
写代码就是一个不断完善的过程,求重复数据、三角形类型、还有日期类的设计,我都有在不断地完善,前文也都有提及。还有的就是和同学交流以及上网查阅资料,学习其他人比自己写得好的地方,才可以做到可持续改进。就如老师上课说的一样,以后的题目只会越来越难,不断地迭代,如果我写的代码只是为了通过测试点而不能做到持续改进,那写以后的题目只会越来越难。
这是我第一次写博客,也是第一次接触到Java这门语言,写到这里又大致浏览了一下我的文章,发现我说的最多的就是和同学讨论以及改进算法。做这两件事的原因也只有一个,那就是避坑。这算是我做这三套题目最大的收获吧!关于上面向对象程序设计的课,虽然我每节课都坐在前排,每节课都没有听懂什么东西,但我觉得这就像我刚刚开始学Java一样,捧着一本Java书看,只能照着书上的程序敲在idea里面,不懂什么叫做类,什么叫做方法,什么叫做对象等等。之后写pta然后到网上看文章学习各种类的使用也算是一只脚踏进了Java的大门吧!对于上课作业实验什么的,我没有什么建议,因为我认为就这样挺好的,虽然不是轻轻松松就能完成,但是如果愿意花时间的话,是能够完成的,而且我也确实能够感觉到我学到了东西。