一. 前言
作为刚学习JAVA的小白,以下只是本人作为普通学生,以当前能力和状态所做出的总结和分析,不足之处也欢迎各位大佬的指正!
第一和第二次题目集的大部分题目难度较低,但是题量较大,主要考了JAVA的格式化输入输出、顺序结构、判断结构、循环结构、浮点运算、分支结构、字符串去重、字符串查找、普通数据查重、去除字符串中指定的部分、素数、字符串多字符分析、读题与分析、普通数据计算、字符串提取、几何形状的判定、JAVA方法的使用。
第三次题目集的难度较前两次有部分提升,且更贴近JAVA的程序设计,但题量较少。主要考察了JAVA中类和方法的使用以及数据的分析处理。
二.代码的设计与分析
因为题目较多,以下只选取部分题目进行分析总结。
1.第一次题目集
7-5 输入一个字符串,输出将其中重复出现的字符去掉后的字符串
以下为源代码:
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner in =new Scanner(System.in); String zfc=in.nextLine(); int n=zfc.length(); //记录字符串的长度 char ch[]=zfc.toCharArray(); //将字符串转为字符数组 int i,j,k; //用于循环的变量 for(i=0;i<n;i++){ for(j=0;j<i;j++){ if(ch[j]==ch[i]){ for(k=i+1;k<n;k++){ ch[k-1]=ch[k]; //发现重复元素则使数组向前缩进(再赋值) } i--; //防止数组缩进后,检查发生遗漏的情况 n--; //使数组参与循环的长度减1 } } }ch[n]='\0';//使字符数组有效长度减少(提前结束) System.out.println(ch); } }
刚开始接触Java还不会用String类。所以这道题我的思路是先把字符串转成字符数组,毕竟字符数组我还是比较熟悉。通过循环嵌套的方式,把当前元素与之前的元素比较,判断是否存在重复,如果存在重复就使后续数组中的元素向前缩进一个元素(本质是下标对应元素的再赋值)。然后再使循环元素i减一,因为如果不减一,下次判断查找会从缩进前下标为i+1的元素开始,遗漏原来下标为i的元素。再使数组长度n减一,这样数组参与循环的数组长度就会减一,最后再使字符数组ch[n]='\0';使字符数组内以字符串输出的有效长度减少,这样再进行输出,就会得到去重后的字符串。
7-10 GPS数据处理。
读入一系列GPS输出,其中包含$GPRMC
,也包含其他语句。在数据的最后,有一行单独的
END
表示数据的结束。
你的程序要从中找出$GPRMC
语句,计算校验和,找出其中校验正确,并且字段2表示已定位的语句,从中计算出时间,换算成北京时间。一次数据中会包含多条$GPRMC
语句,以最后一条语句得到的北京时间作为结果输出。
你的程序一定会读到一条有效的$GPRMC
语句。
以下为源代码:
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner in=new Scanner(System.in); int l,i,r=0,j,m,n,e,f=0; double k=0.0; String p="END";//按题目要求设置结束字符串 String shu=in.nextLine(); int[] jian=new int[100]; l=shu.length();//获得长度 while(shu.compareTo(p)!=0){//判断是否输入结束 r=0;k=0.0; char cun[]=shu.toCharArray();//把输进来的字符转字符数组 if(shu.indexOf("GPRMC")!=-1){//查找“GPRMC” if(shu.indexOf('V')==-1){//查找题目中关键字符‘V’ i=shu.indexOf('$');i++;//indeXOF()查找字符为那个字符串的下标,所以还要再+1,才能使'$'到'*'的字符参与运算 for(;cun[i]!='*';i++){ r=r^cun[i]; //进行题目中的特殊运算 }i++; //使下标指向后两位16进制数转成的字符 for(j=i;j<l;j++){ if(cun[j]>='A'&&cun[j]<='F'){//判断16进制字符 if(cun[j]=='A') f=10; if(cun[j]=='B') f=11; if(cun[j]=='C') f=12; if(cun[j]=='D') f=13; if(cun[j]=='E') f=14; if(cun[j]=='F') f=15; k+=Math.pow(16,l-j-1)*f; //有检测到16进制中的字母则进行该运算 }else{ k+=Math.pow(16,l-j-1)*(cun[j]-'0');//如果未检测到16进制数中的字母,则进行该运算 } } r%=65536;//按照具体题目要求进行换算 if(r*1.0==k){ m=shu.indexOf(',');n=shu.indexOf('.');//获取输入字符串中的UTC时间 String sc=shu.substring(m+1,n); char shi[]=sc.toCharArray();//转为字符数组 e=sc.length(); for(i=0;i<e;i++){ jian[i]=shi[i]-'0';//转为数字类型 }jian[1]=jian[0]*10+jian[1];jian[1]+=8;//得到整数,并转为北京时间 if(jian[1]>24)//判断换算后是否超过24小时 jian[1]-=24; } } } shu=in.nextLine();//接受最后一行字符 if(shu.compareTo(p)==0){ //判断是否输入了“END” if(jian[1]>=10){ //小时处不满10小时补0 System.out.printf("%d:%d%d:%d%d\n",jian[1],jian[2],jian[3],jian[4],jian[5]); }else{ System.out.printf("0%d:%d%d:%d%d\n",jian[1],jian[2],jian[3],jian[4],jian[5]); } } } } }
这一题是输入很多个很长的字符串,要求只提取特定的字符串中的数值,验证是否为特定字符串分几种方式,每个字符串还分很多段,每段之间用','隔开,做这道题时去了解了一些String类的方法,我的思路还是输入转成字符数组,感觉会更加方便判断,设定输入结束的字符串,用compareTo()来判断是否输入结束,然后根据几种判断特殊字符串的方式,通过indexOf()判断那些子字符串的位置,再依次进行判断,用if结构来判断后面16进制的两位字符是否包含16进制中代替数字的字母,再进行进制转换的相关计算。最后再转北京时间输出。
2.第二次题目集
7-9 求下一天,输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。要求使用以下方法:
public static void main(String[] args);//主方法
public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型
public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值
public static void nextDate(int year,int month,int day) ; //求输入日期的下一天
以下为源代码:
import java.util.Scanner; public class Main{ public static void main(String[] args){ //主方法 Scanner in =new Scanner(System.in); int year,month,day; year=in.nextInt(); month=in.nextInt(); day=in.nextInt(); if(checkInputValidity(year,month,day)==true) System.out.println("Wrong Format"); else { nextDate(year,month,day); } } public static boolean checkInputValidity(int year,int month,int day) { //判断输入日期是否合法 int p=0;boolean p1=isLeapYear(year),p2=panduanmonth(month);
if(year<1820||year>2020||month<1||month>12||day<1||day>31) p=1; if(p2==false){ if(p1==false&&month==2) { if(day>28) p=1; } if(p1==true&&month==2) { if(day>29) p=1; } if(month!=2) { if(day>30) p=1; } } if(p==1) return true; else return false; } public static boolean isLeapYear(int year) { //判断year是否为闰年 if(year%400==0&&year%4==0&&year%100!=0) { return true; }else { return false; } } public static boolean panduanmonth(int month) { //判断月份的天数是否为31天 int p=0;
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) { p=1; }else { p=0; } if(p==1) return true; else return false; } public static void nextDate(int year,int month,int day){ //计算并输出下一天 boolean p1=isLeapYear(year),p2=panduanmonth(month); if(month!=2) { //2月份最特殊,先判断是否为2月份 if(p2==true) {//不是二月的同时,判断是否为31天的月份 if(day==31) { if(month!=12) {//是31天的月份则接着判断是否为12月,后续基本就是这三个判断,然后有着对应的程序 day=1;month+=1; }else { year+=1;month=1;day=1; } }else { day+=1; } }else { if(day==30) { day=1;month+=1; }else { day+=1; } } }else { if(p1==true) {//是二月的同时是否为闰年 if(day==29) {//是闰年2月的同时,看是不是29号 month+=1;day=1; }else { day+=1; } }else{ if(day==28) {//是非闰年二月的同时,判断是否为28号 month+=1;day=1; }else { day+=1; } } } System.out.println("Next date is:"+year+"-"+month+"-"+day); } }
这一题的思路主要是按照题目要求,写对应的方法,也是学习了一下Java的方法怎么自己写、自己用,感觉跟C语言差不多。为了方便,还另外写了一个方法,判断非2月月份的天数是否为31天。然后重点就是求计算并输出下一天的方法,换来换去发现还是要从最特殊的2月份的判断开始,这样才比较有逻辑性。是2月份就判断闰年,不是二月份就不用,但是要判断月份最大是否为第31天、是否为第12个月,然后再进行输出就行。
3.第三次题目集
7-3 定义日期类——求下一天,定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。
以下为源代码:
import java.util.Scanner; public class Main{ public static void main(String [] args){ Scanner in =new Scanner(System.in); int year,month,day; year=in.nextInt(); month=in.nextInt(); day=in.nextInt(); Date date=new Date(); date.Date(year, month, day); if(date.checkinputValidity()==false) //判断日期输入是否正确 System.out.println("Date Format is Wrong"); else { date.getNextDate(); } } } class Date{ //日期类 private int year=0; private int month=0; private int day=0; private int[] mon_maxnum=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};//每月的最大天数 void Date(int year,int month,int day) { //有参输入 setyear(year); setmonth(month); setDay(day); } void setyear(int year) { //获取类内的year变量 this.year=year; //使被赋值的year为类里的year } void setmonth(int month) { //获取类内的month变量 this.month=month;//使被赋值的month为类里的month } void setDay(int day) { //获取类内的day变量 this.day=day; //使被赋值的day为类里的day } boolean checkinputValidity(){ //检查日期输入是否正确 boolean judge=true; //设定判断用的boolean型变量 int month,year,day; month=getMonth();year=getYear();day=getDay();//获取类内所需日期变量 if(year<1900||year>2000) judge=false; if(month<1||month>12) judge=false; else { if(month==2) {//以下为分情况判断day的输入是否正确 if(isLeapYear(year)==true) { if(day<1||day>29) judge=false; }else { if(day<1||day>28) judge=false; } }else { if(day<1||day>mon_maxnum(month)) judge=false; } } return judge; } int getYear() {//返回类内year的值 return year; } int getMonth() {//返回类内month的值 return month; } int getDay() {//返回类内day的值 return day; } boolean isLeapYear(int year){//判断是否为闰年 boolean judge=false; if((year%4==0&&year%100!=0)||year%400==0) judge=true; return judge; } int mon_maxnum(int month) {//返回该月份的最大天数 return mon_maxnum[month]; } void getNextDate() { //计算并输出下一天 int year,month,day,maxday; year=getYear();month=getMonth();day=getDay(); maxday=mon_maxnum(month); if(month==12) {//判断是否为12月 if(day==maxday) { year++;month=1;day=1; }else { day++; } }else { if(month==2) {//判断是否为2月 if(isLeapYear(year)==true) { if(day==29) { month++;day=1; }else day++; }else { if(day==28) { month++;day=1; }else day++; } }else { if(day==maxday) { //判断输入的day值是否与该月最大值相等 month++;day=1; }else day++; } } System.out.printf("Next day is:%d-%d-%d",year,month,day);//格式化输出日期 } }
本题与之前那道求下一天的题目类似,但是更贴近Java的编程习惯,采用类+方法的方式来书写。要写的类以及具体要求,题目给的图中已经写出,所以我的思路是先写类,学习了如何实现类后开始着手,定义、日期的变量设成private型,采用set······()来给类内的三个日期相关变量赋值,以get······()来获取三个日期变量的值,再将判断闰年、判断日期输入是否错误的方法放进类中,这次也有单独写一个方法来判断在传进来的月份下最大天数是多少,但是跟上次有很大不一样,上次是方法内通过if语句来判断,而这次是通过mon_maxnum数组来直接获取,方法内只需返回该值即可,当然闰年的2月份还是得单拎出来讨论。然后主方法就主动创建一个Date类,然后通过'.'的方式调用类里面的方法进行输入日期的判断和储存,最后也是用类里的求下一天的方法输出最后结果即可。
圈复杂度:
类图:
7-4 日期类设计,设计一个类DateUtil,该类有三个私有属性year、month、day(均为整型数),其中,year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 除了创建该类的构造方法、属性的getter及setter方法外,需要编写如下方法:
public boolean checkInputValidity();//检测输入的年、月、日是否合法
public boolean isLeapYear(int year);//判断year是否为闰年
public DateUtil getNextNDays(int n);//取得year-month-day的下n天日期
public DateUtil getPreviousNDays(int n);//取得year-month-day的前n天日期
public boolean compareDates(DateUtil date);//比较当前日期与date的大小(先后)
public boolean equalTwoDates(DateUtil date);//判断两个日期是否相等
public int getDaysofDates(DateUtil date);//求当前日期与date之间相差的天数
public String showDate();//以“year-month-day”格式返回日期值
应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
主方法已给出。
以下为源代码:
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();//根据choice的值来判断要使用什么功能 if (choice == 1) { 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);//设立一个DateUtil对象 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(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " 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(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:"); System.out.println(date.getPreviousNDays(n).showDate()); } else if (choice == 3) { 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 " + fromDate.showDate() + " and " + toDate.showDate() + " 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 long year=0; private long month=0; private long day=0; private long[] mon_maxnum=new long[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; public DateUtil(long year, long month, long day) {//有参输入 setyear(year); setmonth(month); setDay(day); } void setyear(long year) {//给对象里的year赋值 this.year=year; } void setmonth(long month) {//给对象里的month赋值 this.month=month; } void setDay(long day) {//给对象里的day赋值 this.day=day; } public boolean checkInputValidity(){//判断是否输入正确 boolean judge=true; long month,year,day; month=getMonth();year=getYear();day=getDay(); if(year<1820||year>2020) judge=false; if(month<1||month>12) judge=false; else { if(month==2) { if(isLeapYear(year)==true) { if(day<1||day>29) judge=false; }else { if(day<1||day>28) judge=false; } }else { if(day<1||day>mon_maxnum(month)) judge=false; } } return judge; } long getYear() {//获取对象里的year值 return year; } long getMonth() {//获取对象的month值 return month; } long getDay() {//获取对象的day值 return day; } public boolean isLeapYear(long year){//判断是否为闰年 boolean judge=false; if((year%4==0&&year%100!=0)||year%400==0) judge=true; return judge; } long mon_maxnum(long month) { return mon_maxnum[(int)month]; } public DateUtil getPreviousNDays(int n) { //获取前n天的日期 long year,month,day,maxday; year=getYear();month=getMonth();day=getDay(); long minusyear=n/365;//先把n中整年的天数提出来,提高代码效率 long leavedays=n%365; //求剩余不满一年的天数 if(n<100000){//如果n不是很大就按如下方法计算日期 for(int i=1;i<minusyear;i++) { if(isLeapYear(year-i)==true) { leavedays--; //每有一次闰年,之前从n天中提出去的整年的天数就要+1,相对的剩余天数减一 ,因为提整年除的是365 } }year-=minusyear; //将提出来的年数用原来的年份减去 }else leavedays=n;//如果n很大就一天一天的加 while(leavedays>0) {//只要还有剩余天数就一直做如下程序 if(month==3) {//判断输入的月份是否为3月,因为减去输入的day后就是2月 if(isLeapYear(year)==true) { if(leavedays-day>=0) { leavedays=leavedays-day;month--;day=mon_maxnum(month)+1; }else { day-=leavedays;//不满输入的day数,就直接减 } }else { if(leavedays-day>=0) {//与上方同理 leavedays=leavedays-day;month--;day=mon_maxnum(month); }else { day-=leavedays; } } }else { if(month==1) {//同理减完day后变为12月 if(leavedays-day>=0) { leavedays=leavedays-day;month=12;day=mon_maxnum(month);year--; }else day-=leavedays; //与month==3的if语句类似 }else { if(leavedays-day>=0) { leavedays=leavedays-day;month--;day=mon_maxnum(month); }else { day-=leavedays;leavedays=0; } } } } return new DateUtil(year,month,day); } public String showDate() { String year=String.valueOf(getYear()); String month=String.valueOf(getMonth()); String day=String.valueOf(getDay()); String result=year+"-"+month+"-"+day; return result; } public DateUtil getNextNDays(int n) {//获得下n天的日期 long year,month,day,maxday; year=getYear();month=getMonth();day=getDay(); long addyear=n/365; long leavedays=n%365; if(leavedays>0) leavedays+=day;//按原来day为0算,故要加上day if(n<1000000) {//与获得前n天的日期同理 for(long i=1;i<addyear;i++) { if(isLeapYear(year+i)==true) { leavedays--; } }year+=addyear; if(month>2&&addyear!=0) { if(isLeapYear(year)==true) leavedays--; } }else { leavedays=n+day; } while(leavedays>0) {//剩余天数不为0就继续 maxday=mon_maxnum(month); if(month==2) { if(isLeapYear(year)==true) { if(leavedays-maxday-1>=0) { leavedays=leavedays-maxday-1;month++;day=1; }else { day+=(leavedays-1);leavedays=0;//减1是因为按数值上其实上一步变化后的day应为0,但日期没有第0天,所以改为赋值为1,计算时要减去 } }else { if(leavedays-maxday>=0) { leavedays=leavedays-maxday;month++;day=1; }else { day+=(leavedays-1);leavedays=0;//同上 } } }else { if(month==12) { if(leavedays-maxday+day>=0) { leavedays=leavedays-maxday;month=1;day=1;year++; }else { day+=(leavedays-1);leavedays=0; } }else { if(leavedays-maxday>=0) { leavedays=leavedays-maxday;month++;day=1; }else { day+=(leavedays-1);leavedays=0; } } } } return new DateUtil(year,month,day);//返回DateUtil对象 } public long getDaysofDates(DateUtil date) {//输出相差了几天 long yearnumber=Math.abs(date.getYear()-year);//求年数相差的绝对值 long daynumber=Math.abs(date.getDay()-day);//求天数相差的绝对值 long resultday=yearnumber*365;//把相隔的年数乘365得出天数 if(date.getYear()-year<0) { //如果输入的年份早于对象中的 for(int i=0;i<yearnumber;i++) { if(isLeapYear(date.getYear()+i)==true) { resultday++;//每有一个闰年,天数+1 } } if(date.getMonth()<=2) {//判断对象的month是否小于2月 for(int i=1;i<date.getMonth();i++) { resultday-=mon_maxnum(i); } resultday-=date.getDay(); }else { for(int i=1;i<date.getMonth();i++) { if(i!=2) resultday-=mon_maxnum(i); else { if(isLeapYear(year)==true) { resultday-=mon_maxnum(i)-1;//因为该数组2月对应的最大天数为28天 }else resultday-=mon_maxnum(i); } } resultday-=date.getDay(); } for(int i=1;i<month;i++) {//计算最后隔了多少个月 if(i!=2) resultday+=mon_maxnum(i); else { if(isLeapYear(year)==true) { resultday+=(mon_maxnum(i)+1); }else resultday+=mon_maxnum(i); } } resultday+=day; } if(date.getYear()-year==0){//如果同年同月怎么计算 if(date.getMonth()-month<=0) { for(long i=date.getMonth();i<month;i++) { if(i==2) { if(isLeapYear(year)==true) { resultday+=(mon_maxnum(i)+1); }else resultday+=mon_maxnum(i); }else resultday+=mon_maxnum(i); }resultday+=daynumber; }else { for(long i=month;i<date.getMonth();i++) { if(i==2) { if(isLeapYear(year)==true) { resultday+=(mon_maxnum(i)+1); }else resultday+=mon_maxnum(i); }else resultday+=mon_maxnum(i); }resultday+=daynumber; } } if(date.getYear()-year>0) {//如果输入的年份晚于对象中的 for(int i=0;i<yearnumber;i++) { //以下与上面代码前面类似 if(isLeapYear(year+i)==true) { resultday++; } } if(month<=2) { for(int i=1;i<month;i++) { resultday-=mon_maxnum(i); } resultday-=day; }else { for(int i=1;i<month;i++) { if(i!=2) resultday-=mon_maxnum(i); else { if(isLeapYear(year)==true) { resultday-=mon_maxnum(i)-1; }else resultday-=mon_maxnum(i); } } resultday-=day; } for(int i=1;i<date.getMonth();i++) { if(i!=2) resultday+=mon_maxnum(i); else { if(isLeapYear(date.getYear())==true) { resultday+=(mon_maxnum(i)+1); }else resultday+=mon_maxnum(i); } } resultday+=date.getDay(); } return resultday; } public boolean equalTwoDates(DateUtil date) {//比较两个日期是否相等 if(date.getDay()==day&&date.getMonth()==month&&date.getYear()==year) { return true; }else return false; } public boolean compareDates(DateUtil date) {//比较两个日期谁更早 int judge=0; if(year<date.getYear()) { judge=1; }if(year>date.getYear()) { judge=2; } if(judge==0) { if(month<date.getMonth()) { judge=1; } if(month>date.getMonth()) { judge=2; } if(judge==0) { if(day<date.getDay()) { judge=1; } if(day>date.getDay()) { judge=2; } } } if(judge==1) { return true; } if(judge==2||judge==0) { return false; } return false; } }
我的思路是:因为主方法已给出,所以需要根据主方法来写类,其它必要的方法也都在题目内给出,除了三个方法,其它方法都跟前面求日期的题目差不多。第一个是求下n天的日期,在n不是很大的时候,先除365看看隔了几年,再加上现在对象的年份求出大致最终年份,然后用循环判断闰年,每有一个闰年提出年份后的剩余天数-1+上对象的day数,再把对象天数当做0,然后整月整月的加,每个月的最大天数,那个mon_maxnum数里有,只需注意闰年二月和12月更新年份,最容易忽略的点是:因为day没有第0天,所以在加一个月后,会给day赋值为1,在最后剩余天数不足一个月时,就得把天数直接加到day上,此时要把之前赋值给day的1减掉,否则会多一天,因为在计算中实际上那个时候day=0。当n很大时,可能因为闰年的关系,实际给对象加的年数是小于算出来的值的,这时候就直接整月整月的加,来避免错误;第二个是求前n天的日期,与求下n天日期差不多,只不过加变成减,有一个不同的地方就是无需在最后天数不满一个月时减一,因为最后是用30或31去减,不会多余;第三个是求两日期间隔天数
圈复杂度:
类图:
三.遇到的问题与解决后的心得
1.第一次题目集
7-5
遇到了重复元素只去掉了一部分的情况,在数组缩进后加上i--;。缩进后数组内元素发生了位置变化,这个很容易遗漏,需注意。
7-10
忽略了indexOf()查找字符获得的下标是该字符的下标的事实,忘记将下标再往后移一个单位。这种字符下标搞错的情况还是很容易发生的,写着写着就漏了再移一位,写代码时还是要把下标、变量的值记明白,想清楚,这样才能更好地运用。在该方法后加上i++;即可。
2.第二次题目集
7-9
忘记在月份更新时给day再赋值为1,导致了日期显示day为0的情况,日期没有第0天,这个被我忽略了,还是得仔细想想输出的格式中所内含的一些东西。在月份更新处加个day=1;即可。
3.第三次题目集
7-3
未发生错误
7-4
1)求下n天,当n很大时会出错,因为在从n中取整年的天数时是默认都是365天一年,后续再通过循环来加上闰年缺失的那部分,这种方法在取完整年,整年中闰年的个数少于剩余天数时才有效,不然就会错误,剩余天数出现负值,整年取的偏大,后续是通过加判断,使n很大时直接采用整月整月加的方式计算才解决。这个错误提醒了我在设计程序的时候要多多考虑其适用范围,免得出现不在适用范围内而导致出错的情况,以下为正确结果:
2)求前n天
除了上述同样的问题以外,还有忽略了当前年份为闰年,而当前月份大与2时的多出的那一天。因为采取先减整年的方式,所以会出现减完年份后为平年,而初始为闰年的情况,导致最后结果多减了一天,比如上面图片中结果就应该是2-28,对于数据变化的初始状态和末尾状态的关注还是不够,所以才会犯这种错误。在减年份之前多加一个嵌套判断语句看是不是初始月份超过2月,初始年份是否为闰年就可以了。
3)求两日期间隔天数
忽视了两日期同年或同月的情况,导致答案错误。我对于数据变化的情况还是想的不够全面,漏了这种情况,之后做题还是要更加仔细的思考。加上相关判断语句和相关程序,改为从月份开始比较,进行计算,对于也同月的则从天数开始计算,就可以改正错误。以下为正确结果:
四.代码优化的想法
刚开始学Java,代码风格还是偏向c语言,套用的c语言的模式,也没用到什么Java的语法和结构,像第一二题目集的例子中将字符串转为字符数组,其实大可不必,直接用String类的方法就可以解决问题,然后对类以及方法的设计和使用还不够熟练,应该多用用,使每个方法实现单一功能。代码中为求简单,我的变量、方法、数组之类的命名都是直接用字母或拼音缩写,导致可读性不高,以后得多多注意,多用英文来命名。还有就是在PTA提交的源码没有注释,也导致了可读性下降,后续我会写一些,保持良好习惯。
五.学习总结和对现有学习模式的建议
目前的自己的Java学习进度还是太慢了,一方面是有很多其它的事,导致时间被挤占,另一方面则是自己学习效率确实是偏低,目前自己只学会了很基本的Java语法和一些类的方法。以后还是得加强时间管理,增加学习Java的时间,多多与同学沟通,增加自己的学习效率。对于老师上课重点提到的方法和类得加强自学,对于已知的方法和类还要增加熟练度,平时多看看相关的书,增加自己对面向对象的理解,体会类的设计。对于现有教学模式感觉还可以,也才刚开始几周,目前也没什么意见和建议。
以上就是我对Java学习第一阶段的三次题目集和当前学习的小小总结。
标签:leavedays,题目,int,month,year,三次,Java,else,day From: https://www.cnblogs.com/JH2213/p/17251170.html