今年是大二下学期,也是专业课集中学习的开始,这是本学期的第一篇博客。由于是新手上路,写的不好的地方还请各位大神指点一下。这篇博客围绕这一个月来学习java的心得体会,当然,代码是少不了的,主要是以pta上的三次作业为参考。写这篇博客目的在于自我反思,为以后的学习提供一个对比物。接下来,我将尝试用这篇博客来解释其中的种种困难,看不下去的朋友可以到此止住了。
这三次作业是以java程序编写日历为主,第一次作业主要是让我们了解并熟悉java基本程序,当然,多于新手来说,尤其是对于依然宅在家学习网课的我们学生来说,里面的程序题目看起来似乎并不简单。话不多说,直接上一个代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int a=sc.nextInt();
double b=sc.nextDouble();
double c;
if(a>=0&&a<=3&&b>0)
{
switch(a) {
case 0:
{
if(b<=8350) {c=0.1*b;System.out.println(c);break;}
if(b<=33950) {c=0.1*8350+0.15*(b-8350);System.out.println(c);break;}
else if(b<=82250) {c=0.1*8350+0.15*25600+0.25*(b-33950);System.out.println(c);break;}
else if(b<=171550) {c=0.1*8350+0.15*25600+0.25*48300+0.28*(b-82250);System.out.println(c);break;}
else if(b<=372950) {c=0.1*8350+0.15*25600+0.25*48300+0.28*89300+0.33*(b-171550);System.out.println(c);break;}
else {c=0.1*8350+0.15*25600+0.25*48300+0.28*89300+0.33*201400+0.35*(b-372950);System.out.println(c);break;}
}
case 1:
{
if(b<=16700) {c=0.1*b;System.out.println(c);break;}
if(b<=67900) {c=0.1*16700+0.15*(b-16800);System.out.println(c);break;}
else if(b<=137050) {c=0.1*16700+0.15*51200+0.25*(b-67900);System.out.println(c);break;}
else if(b<=208850) {c=0.1*16700+0.15*51200+0.25*69150+0.28*(b-137050);System.out.println(c);break;}
else if(b<=372950) {c=0.1*16700+0.15*51200+0.25*69150+0.28*71800+0.33*(b-208850);System.out.println(c);break;}
else {c=0.1*16700+0.15*51200+0.25*69150+0.28*71800+0.33*164100+0.35*(b-372950);System.out.println(c);break;}
}
case 2:
{
if(b<=8350) {c=0.1*b;System.out.println(c);break;}
if(b<=33950) {c=0.1*8350+0.15*(b-8350);System.out.println(c);break;}
else if(b<=68525) {c=0.1*8350+0.15*25600+0.25*(b-33950);System.out.println(c);break;}
else if(b<=104425) {c=0.1*8350+0.15*25600+0.25*34575+0.28*(b-68525);System.out.println(c);break;}
else if(b<=186476) {c=0.1*8350+0.15*25600+0.25*34575+0.28*35900+0.33*(b-104425);System.out.println(c);break;}
else {c=0.1*8350+0.15*25600+0.25*34575+0.28*35900+0.33*82051+0.35*(b-186476);System.out.println(c);break;}
}
case 3:
{
if(b<=11950) {c=0.1*b;System.out.println(c);break;}
if(b<=45500) {c=0.1*11950+0.15*(b-11950);System.out.println(c);break;}
else if(b<=117450) {c=0.1*11950+0.15*33550+0.25*(b-45500);System.out.println(c);break;}
else if(b<=190200) {c=0.1*11950+0.15*33550+0.25*71950+0.28*(b-117450);System.out.println(c);break;}
else if(b<=372950) {c=0.1*11950+0.15*33550+0.25*71950+0.28*72750+0.33*(b-190200);System.out.println(c);break;}
else {c=0.1*11950+0.15*33550+0.25*71950+0.28*72750+0.33*182750+0.35*(b-372950);System.out.println(c);break;}
}
default:System.out.println("Wrong Format");
}
}else System.out.println("Wrong Format");
}
}
这是一道关于税率计算的题目,大家也都看到了,里面的代码并不简洁,看起来也有点累赘,对于一个新手来说,光是敲打这个代码就花费了不少时间,这还只是第一题,其中还有临界点的测试等等,说实在的,真的不容易,相信很多人也有这种想法,尤其是在临界点的测试上面,老是出错,一直找不到原因,另一方面,因为是宅在家里,不是在学校,对于一些细节问题还得靠自己解决,不得不说的是,程序员的生活真不简单。这个代码测试出来以后,并不是很理想,但也是无可奈何,光是临界点的测试就花费了大半时间,里面的临界点测试也是让人捉急,找了好久也没找出来,然后就那样子了。这个代码主要是以面向过程来写的,就是光解决问题的不考虑代码的重复利用率那种,可能是用不到吧,加上不太熟练面向过程的,就按照c语言的方式来写了。
没过了几天,第二次作业也出了出来,这次作业主要是关于日期的设计,万年历大家都耳熟能详,pta的这次和下次作业便是以万年历为主要设计方向。同样的,也是代码为主
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
//System.out.print("Plese input the year:");
int year=sc.nextInt();
int month=sc.nextInt();
int day=sc.nextInt();
nextDate(year,month,day);
}
public static boolean isLeapYear(int year) {
if(year%4==0 && year%100!=0){
return true;
}else if(year%400==0){
return true;
}else
{
return false;
}
}
public static boolean checkInputValidity(int year,int month,int day) {
if(year>=1820&&year<=2020&&month>=1&&month<=12&&day>=1&&day<=31&&!isLeapYear(year)&&month==2&&day>28)
return false;//System.out.print("Wrong Format");
else if(year>=1820&&year<=2020&&month>=1&&month<=12&&day>=1&&day<=31)
return false;
}
public static void nextDate(int year,int month,int day) {
int y,m,d;
if(checkInputValidity(year,month,day))
{
if((month==1||month==3||month==5||month==7||month==8||month==10)&&day<31)
{
y=year;m=month;d=day+1;
System.out.print("Next date is:"+y+"-"+m+"-"+d);
}
if((month==1||month==3||month==5||month==7||month==8||month==10)&&day==31) {
y=year;m=month+1;d=1;
System.out.print("Next date is:"+y+"-"+m+"-"+d);
}
if((month==4||month==6||month==9||month==11)&&day<30) {
y=year;m=month;d=day+1;
System.out.print("Next date is:"+y+"-"+m+"-"+d);
}
if((month==4||month==6||month==9||month==11)&&day==30) {
y=year;m=month+1;d=1;
System.out.print("Next date is:"+y+"-"+m+"-"+d);
}
if(month==12&&day<31) {
y=year;m=month;d=day+1;
System.out.print("Next date is:"+y+"-"+m+"-"+d);
}
if(month==12&&day==31) {
y=year+1;m=1;d=1;
System.out.print("Next date is:"+y+"-"+m+"-"+d);
}
if(month==2&&day<29&&isLeapYear( year)) {
y=year;m=month;d=day+1;
System.out.print("Next date is:"+y+"-"+m+"-"+d);
}
if(month==2&&day==29&&isLeapYear( year)) {
y=year;m=month+1;d=1;
System.out.print("Next date is:"+y+"-"+m+"-"+d);
}
if(month==2&&day<28&&!isLeapYear( year)) {
y=year;m=month;d=day+1;
System.out.print("Next date is:"+y+"-"+m+"-"+d);
}
if(month==2&&day==28&&!isLeapYear( year)) {
y=year;m=month+1;d=1;
System.out.print("Next date is:"+y+"-"+m+"-"+d);
}
}else System.out.print("Wrong Format");
}
}
这个代码求的是一个日期的下一天,当时看到这个题目,也是懵了好久,早上看的,动手写的时候已经是中午了,之间上网查找了一些关于年月日的计算公式,比如闰年和平年的概念等,写的时候还列了好大的草稿,按照四年一次的循环方式,对四年来的每一天都总结了一下,然后才开始写代码,思维知道了,但写出来的时候调用关系之类的还是参考pta给出的类来写的,要是自己想的话,可能会直接用c语言的方式来直接写,并不会调用什么。里面的测试点也让人很头疼,有一个测试点记得很清楚,是关于平年29号的,其他测试点都对了,说句不好听的话,这个测试点真的不不咋地,顶多就是多写点代码单独解决就是,不过这个测试点出来以后,我马上对29,30,31这三个日子代入了一下,最后发现我的代码好像还有点问题,可能这就是所说的bug了,代码本身没有错,关键是有不能解决的问题出现了,bug便产生了,也是一个头两个大了,想了好久都没有解决方法,除非重新写过,那样的话还不一定写得出来,所幸的是,测试点都过了,这个代码便不了了之。不过写了这个代码过后,我发现测试用例还真的很不一般,能想出来的人也肯定不一般,因为如果换做是我来想的话,这些测试用例肯定不齐全。
前面已经提了一下,三次作业都是以日历为主,第三次也不例外,但第三次的第一题是用面向过程的思想来解决二元一次方程的题目,这道题目在第一次作业中也有过,不过我是直接带用公式解出来的,并没有用类的思想,而这次换成了必须以类的思想来解决问题,于是多写了几个类来辅助解决问题。对于这道题目,我真觉得用类来写没什么用,可能是我的代码储存量不够多。不过第三次作业的二三四题就不一样了,题目差不多,都是解决一个日期的下几天、前几天还有两个日期之间相差多少天,有区别的是三四题多了关于年月日的单独类的编写以及调用关系的差别,解决的还是那几个问题。也是一样的,直接上代码
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int year = 0;
int month = 0;
int day = 0;
int choice = input.nextInt();
if (choice == 1) { // test getNextNDays method
int m = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
m = input.nextInt();
if (m < 0) {
System.out.println("Wrong Format");
System.exit(0);
}
System.out.print(year + "-" + month + "-" + day + " next " + m + " days is:");
System.out.println(date.getNextNDays(m).showDate());
} else if (choice == 2) {
int n = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
n = input.nextInt();
if (n < 0) {
System.out.println("Wrong Format");
System.exit(0);
}
System.out.print(year + "-" + month + "-" + day + " previous " + n + " days is:");
System.out.println(date.getPreviousNDays(n).showDate());
} else if (choice == 3) { //test getDaysofDates method
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
int anotherYear = Integer.parseInt(input.next());
int anotherMonth = Integer.parseInt(input.next());
int anotherDay = Integer.parseInt(input.next());
DateUtil fromDate = new DateUtil(year, month, day);
DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
System.out.println("The days between " + year+"-"+month+"-"+day + " and " + anotherYear+"-"+anotherMonth+"-"+anotherDay +" are:"
+ fromDate.getDaysofDates(toDate));
} else {
System.out.println("Wrong Format");
System.exit(0);
}
}
else{
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class DateUtil{
private int year,month,day;
public DateUtil(int year, int month, int day) {
setYear(year) ;
setMonth(month);
setDay(day);
}
public boolean checkInputValidity() {
if(year>=1820&&year<=2020&&month>=1&&month<=12&&day>=1&&day<=31&&!isLeapYear(year)&&month==2&&day>28) return false;
else if(year>=1820&&year<=2020&&month>=1&&month<=12&&day>=1&&day<=31) return true;
else return false;
}
public void setYear(int year) {
this.year=year;
}
public double getYear() {
return year;
}
public void setMonth(int month) {
this.month=month;
}
public double getMonth() {
return month;
}
public void setDay(int day) {
this.day=day;
}
public double getDay() {
return day;
}
public boolean isLeapYear(int year) {
if(year%4==0 && year%100!=0){
return true;
}else if(year%400==0){
return true;
}else
{
return false;
}
}
public DateUtil getNextNDays(int n) {
int i=0,y=year,m=month,d=day;
while(n>=366)
{
if(isLeapYear(y)) { y++;n=n-366; }
else { y++;n=n-365; }
}
while(i<n)
{
if(m==1||m==3||m==5||m==7||m==8||m==10||m==12)
{
if(d==31)
{
if(m==12) { y++;m=1;d=1; }
else { m++;d=1; }
}
else if(d<31) d++;
}
else if(m==4||m==6||m==9||m==11)
{
if(d==30) { m++;d=1; }
else if(d<30) d++;
}
else if(m==2&&isLeapYear(y))
{
if(d==29) { m++;d=1; }
else d++;
}
else if(m==2&&!isLeapYear(y))
{
if(d==28) { m++;d=1; }
else d++;
}
i++;
}
DateUtil date = new DateUtil(y,m,d);
return date;
}
public String showDate()
{
String s;
s=String.valueOf(year)+"-"+String.valueOf(month)+"-"+String.valueOf(day);
return s;
}
public DateUtil getPreviousNDays(int n) {
int i=0,y=year,m=month,d=day;
while(n>=366)
{
if(isLeapYear(y)) { y--;n=n-366; }
else { y--;n=n-365; }
}
while(i<n)
{
if(m==1||m==2||m==4||m==6||m==8||m==9||m==11)
{
if(d==1)
{
if(m==1) { y--;m=12;d=31; }
else { m--; d=31; }
}
else d--;
}
else if(m==3&&d==1&&isLeapYear(y)) { m--;d=29; }
else if(m==3&&d==1&&!isLeapYear(y)) { m--;d=28; }
else if(m==3&&d>1) d--;
else if(m==5||m==7||m==10||m==12)
{
if(d==1) { m--;d=30; }
else if(d>1) d--;
}
i++;
}
DateUtil date = new DateUtil(y,m,d);
return date;
}
public boolean equalTwoDates(DateUtil date)
{
if(year==date.getYear()&&month==date.getMonth()&&day==date.getDay()) return true;
else return false;
}
public boolean compareDates(DateUtil date)
{
if(year==date.getYear()&&month<date.getMonth()&&day<date.getDay()) return true;
else if(year==date.getYear()&&month<date.getMonth()) return true;
else if(year<date.getYear()) return true;
else return false;
//else return false;
//else return false;
}
public String getDaysofDates(DateUtil toDate) {
return null;
}
}
代码有点长,三百来行,确实不容易,虽然有了第二次作业代码的参考,写出来还是花费了很多功夫,里面关于每个日期的测试也是下了一番苦功,带用了好多日期,把手机上的万年历都拿出来做对比,但由于日期太多了,最后还是免不了出错,另外,关于天数差的那个代码,想了好多方法,但是不够具体,比如可以先求下一天,再用迭代的方式来写,可是对代码的认知不够,并不能写出来,即使写出来运行时有好多问题,最后老老实实用按当初学c语言的方式来写。其中两日期相差的天数并没有写出来,实在是想不来了,真的是难。其实依我之见,面向过程有种像调用函数的意思,c语言中的函数到了java中就称之为方法,c语言的变量也成了对象。然后为了好调用,便产生了类,在c语言中是无法调用其符主函数的,但在java中只要少用一个public便可以调用。另外,mooc上java的核心技术讲解视频有种想把java设计成一个机器世界的意思,里面的各种继承之类的也合我们人类数千年来的发展规律,多的话也说不出来,还需要继续体会,接下来就是最后的总结了。
总而言之,这三次作业一次比一次更具有代表性,可以让我们从面向过程逐步步入到对象的思维中去,这三次作业花费的时间都是零零散散,问题也并不是一次就解决出来,如果非要用一个时间比来表示来说明这三次作业花费时间的话,我觉得1:1:1这个比再合适不过了,因为人总是要在学习和实践中不断成长的,题目会越来越难,人也是会慢慢吸取经验的。有一点不得不说的时,编写代码的时候真的要很严谨的思维,不然bug总会不断出现,在测试的时候,也会过不了。即使过的了一个测试点,零一点正确的测试点说不定有错了,总之要统筹兼顾把测试点一次都过了。其实对这门课程,我有个小小的不成熟的意见,那就是测试点多虽然可以提升我们的严谨性,但在这上面花费的时间并不比重新写代码所花的时间要少,与其在这上面花费这么多时间,不如降低测试点的难度,去学习一些新知识,到头来还可以温故而知新,说不定有更不一样的思维或想法。或者是延长pta所花的时间,让我们能更好的去修改代码,毕竟学的多写出来的代码也就更多,也就不会有什么想得到许多解觉方案但动手难的问题。又或者可以在课程结束后一个月内,让我们可以一次修改代码等等之类的。
趁着这次清明扫墓回来,又润色了一下,终于是写完这第一篇博客,中途也陆陆续续修改了一部分,终归是有个良好的开端,接下来可能会经常在这上面发表,还望各位大V多多指教,一起进步,也带带我们,让我们也成为大佬。