PTA题目集1~3总结
[TOC]
一·前言:
(1)经历了前3次PTA作业,考查的知识点很多。首先,题目集1主要考考察java前八章的基本语法,有变量的类型,输入与输出,循环语句和选择语句,强制转化变量的类型,(字符串)数组的输入与输出,字符串的输出和输入,switch语句,和for语句,及if语句的语法和逻辑,数学函数的应用,以及java的编译器eclipse的数据误差,而题目集3和题目集1,2的最大区别就是考察了java的类和方法的应用,还有类的聚合,耦合性,简单的类间关系,还有聚合的强内聚性。
(2)题目集的题量区别大,题目集1有9个题目,题量大,题目集2有3个题目,题目集3有4个题目,但是难度不同。
(3)题目集1的难度现在看来不大(但是当时也写的很难受),所以题目量多一点,考察我们细心和和对知识的掌握,对我们前几周自学能力的考察,因为我们当时是自学。题目集2是我们题目集1的升级,主要考察了String类型和字符串。难度比第一次大。第三次题目集主要考察类和对象,难度最大,代码行数最多,类写的也一题比一题多。
(4)我的做题时间比较长,因为我基础不太好,但是最后也写完了(在同学帮助下)。
二·设计与分析:
(1)题目集1源码分析如下:
import java.util.Scanner; public class Main{ public static void main(String[] args) { java.util.Scanner in = new java.util.Scanner(System.in); Scanner input=new Scanner(System.in); double w= input.nextDouble(); double h= input.nextDouble(); double bmi=(w/(h*h)); if(w>727||h>2.72||w<=0||h<=0) { System.out.println("input out of range"); } else if(bmi<18.5&&bmi>0) { System.out.println("thin"); } else if(bmi>=18.5&&bmi<=24) { System.out.println("fit"); } else if(bmi>24&&bmi<=28) System.out.println("overweight"); else if(bmi>28) { System.out.println("fat"); } }}
*这一题主要考察身体质量指数(BMI)测算,计算方法为:体重(以千克为单位)除以身高(以米为单位)的平方。中国成人正常的BMI应在18.5-24之间,如果小于18.5为体重不足,如果大于等于24为超重,大于等于28为肥胖。这题只需要先计算出BMI指数,在使用if和else if语句进行判断。
import java.util.Scanner; public class Main{ public static void main(String[] args) { java.util.Scanner in = new java.util.Scanner(System.in); Scanner input=new Scanner(System.in); float kg= input.nextFloat(); float m = input.nextFloat(); float bang,arce; bang=(float)(kg/0.45359237); arce=(float)(m/0.0254); System.out.print(bang+" "+arce); } }
*这一题考察长度质量计量单位换算,编写程序实现国际单位制与英制之间的换算。要注意强制转化变量的类型,将double转换成float型,否则过不了,小数保留会出错。
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner input=new Scanner(System.in); int s=0; int[] a=new int [10]; for (int i = 0; i < 10; i++) { a[i]=input.nextInt(); if(a[i]%2!=0) { s=s+a[i]; } } System.out.println(s); } }
*这一题是奇数求和,计算一个数列中所有奇数的和,输入数列中所有奇数之和,这一题要注意算法,要多思考。
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner input=new Scanner(System.in); int zz= input.nextInt(); int js= input.nextInt(); if(zz<=0||zz>4||js<0||js>3) { System.out.print("Wrong Format"); } else { switch(zz) { case 1:System.out.print("人类");break; case 2:System.out.print("精灵");break; case 3:System.out.print("兽人");break; case 4:System.out.print("暗精灵"); break; } switch(js) { case 1:System.out.print(" "+"战士");break; case 2:System.out.print(" "+"法师");break; case 3:System.out.print(" "+"射手");break; } } } }
*这一题目有意思,是游戏角色选择,一款网游中包括4个种族:人类、精灵、兽人、暗精灵,每个种族包含三种角色:战士、法师、射手。玩家新建人物时需要选择种族和角色。要编写角色选择程序,这题可以用switch语句或if,else if语句来写,我这里用的是switch语句,因为switch语句代码量比if语句少,更简单,就是要注意输出格式。
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner input=new Scanner(System.in); String s=input.next(); if(s.length()!=8) { System.out.println("Wrong Format"); System.exit(0); } if(s.charAt(2)=='0'&&s.charAt(3)=='1') { System.out.print("入学年份:"); char ch=s.charAt(0); char ch1=s.charAt(1); System.out.println("20"+s.charAt(0)+s.charAt(1)+"年"); char ch2=s.charAt(2); char ch3=s.charAt(3); System.out.print("学院:"); System.out.println("材料学院"); } else if(s.charAt(2)=='0'&&s.charAt(3)=='2') { System.out.print("入学年份:"); char ch=s.charAt(0); char ch1=s.charAt(1); System.out.println("20"+s.charAt(0)+s.charAt(1)+"年"); char ch2=s.charAt(2); char ch3=s.charAt(3); System.out.print("学院:"); System.out.println("机械学院"); } else if(s.charAt(2)=='0'&&s.charAt(3)=='3') { System.out.print("入学年份:"); char ch=s.charAt(0); char ch1=s.charAt(1); System.out.println("20"+s.charAt(0)+s.charAt(1)+"年"); char ch2=s.charAt(2); char ch3=s.charAt(3); System.out.print("学院:"); System.out.println("外语学院"); } else if(s.charAt(2)=='2'&&s.charAt(3)=='0') { System.out.print("入学年份:"); char ch=s.charAt(0); char ch1=s.charAt(1); System.out.println("20"+s.charAt(0)+s.charAt(1)+"年"); char ch2=s.charAt(2); char ch3=s.charAt(3); System.out.print("学院:"); System.out.println("软件学院"); } else { System.out.println("Wrong Format"); System.exit(0); } char ch4=s.charAt(4); char ch5=s.charAt(5); System.out.print("班级:"); System.out.print((s.charAt(4))); System.out.println((s.charAt(5))); char ch6=s.charAt(6); char ch7=s.charAt(7); System.out.print("学号:"); System.out.print((s.charAt(6))); System.out.println((s.charAt(7))); } }
*这一题考察了字符串,它比前几题更难,考察学号识别,学校的学号由8位数字组成,前两位是入学年份(省略了20);第3、4位是学院编号,01代表材料学院,02代表机械学院,03代表外语学院,20代表软件学院;第5、6位是学院内部班级编号,最后两位是班级内部学号。如:18011103,入学年份是2018年,材料学院,11班,03号,
入学年份:2018年
学院:材料学院
班级:11
学号:03
注意:如非法输入,输出“Wrong Format"
*输入学号,然后上面是本题的输出格式。这题要将学号作为一个字符串,然后用charAt(),这个函数一个一个提取出来进行判断(if语句),但是要注意字符串也是从0开始,输出格式也要注意,print不换行,println换行。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); float n = input.nextFloat(); float lastGuess=input.nextFloat(); float nextGuess=(lastGuess + n/lastGuess)/ 2; if(n<0||lastGuess<=0) { System.out.println("Wrong Format"); } else { for (;Math.abs(nextGuess-lastGuess)>= 0.00001 ;){ lastGuess=nextGuess; nextGuess = (float)(lastGuess + n/lastGuess )/2; } System.out.println(lastGuess); } }}
*这一题是,巴比伦法求平方根近似值,比伦法求n的近似值可以用以下公式:
*这一题是,巴比伦法求平方根近似值,比伦法求n的近似值可以用以下公式:
nextGuess = (lastGuess+n/lastGuess)/2
程序初始运行时lastGuess可赋予一个最初的猜测值。当由公式求得的nextGuess和lastGuess相差较大时,把nextGuess的值赋给lastGuess,继续以上过程,直至nextGuess和lastGuess几乎相同,此时lastGuess或者nextGuess就是平方根的近似值。
本题要求:nextGuess和lastGuess的差值小于0.00001时认为两者几乎相同
*这一题要注意它们的相差的值为0.00001;
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); String s=input.nextLine(); int i=0; for(i=0;i<s.length();i++) { if((s.charAt(i)=='-')&&(s.charAt(i+1)=='1')) { break; } } if(i==s.length()) System.out.println("Wrong Format"); else { for(i=0;i<s.length();i++) { if(s.charAt(i)=='1'||s.charAt(i)=='0') System.out.print(s.charAt(i)); if((s.charAt(i)=='-')&&(s.charAt(i+1)=='1')) break; } } } }
*这一题考察在一个字符串中提取出其中的二进制数值序列,一个由0、1构成的序列,以-1为结束符,非0、1字符视为正常输入,但忽略不计,未包含结束符的序列视为非法输入。将输入的序列去掉非0、1字符以及结尾符的数据内容。
*这题与上面那题一样,都是用字符串,这题是要遍历一下字符串,去掉非0、1字符以及结尾符,再输出即可。
(2)题目集2分析与代码如下:
*题目1:输入一个由英文字母组成的字符串(大小写均可),将所有英文字母转换成它们在字母表中的序号,例如:“AbbcD”转换为“12234”
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input=new Scanner(System.in); String s = input.nextLine(); int k=0; boolean a=false; for(int i=0;i<s.length();i++) { if(s.charAt(i) >= 'A'&&s.charAt(i)<='Z'||s.charAt(i) >= 'a'&&s.charAt(i) <='z') a=true; else { a=false; break; } } if(a==false) System.out.print("Wrong Format"); else { for(int i=0;i<s.length();i++) { if(s.charAt(i) >= 'A'&&s.charAt(i)<= 'Z') { k= s.charAt(i) - 64; System.out.print(k); } else if (s.charAt(i) >= 'a'&&s.charAt(i) <= 'z') { k= s.charAt(i) - 96; System.out.print(k); } } } } }
*这一题也是使用字符串进行遍历,找大小写字母,然后输出,要利用ASCII字符集表判断字母,要注意出现非字母输出Wrong Format。
*题目2:
串口字符解析 (50 分)
RS232是串口常用的通信协议,在异步通信模式下,串口可以一次发送5~8位数据,收发双方之间没有数据发送时线路维持高电平,相当于接收方持续收到数据“1”(称为空闲位),发送方有数据发送时,会在有效数据(5~8位,具体位数由通信双方提前设置)前加上1位起始位“0”,在有效数据之后加上1位可选的奇偶校验位和1位结束位“1”。请编写程序,模拟串口接收处理程序,注:假定有效数据是8位,奇偶校验位采用奇校验。
输入:由0、1组成的二进制数据流。例如:11110111010111111001001101111111011111111101111
输出:过滤掉空闲、起始、结束以及奇偶校验位之后的数据,数据之前加上序号和英文冒号。
如有多个数据,每个数据单独一行显示。
若数据不足11位或者输入数据全1没有起始位,则输出"null data",
若某个数据的结束符不为1,则输出“validate error”。
若某个数据奇偶校验错误,则输出“parity check error”。
若数据结束符和奇偶校验均不合格,输出“validate error”。
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner input=new Scanner(System.in); int sum=1; int aut=0; int c=0; String s=input.nextLine(); for(int i=0;i<s.length();i++) { if(s.charAt(i)=='1') c++; } if(s.length()<11||c==s.length()) System.out.println("null data"); else { for(int i=0;i<s.length();i++) { if(s.charAt(i)=='0') { aut=0; for(int j=i+1;j<i+9;j++) { if(s.charAt(j)=='1') aut++; } if(s.charAt(i+10)!='1') { System.out.println(sum+":"+"validate error"); sum++; i=i+10; } else if(aut%2==0&&s.charAt(i+9)!='1') { System.out.println(sum+":"+"parity check error"); sum++; i=i+10; } else if(aut%2!=0&&s.charAt(i+9)!='0') { System.out.println(sum+":"+"parity check error"); sum++; i=i+10; } else { System.out.println(sum+":"+s.substring(i+1,i+9)); sum++; i=i+10; } } } } } }
*这题主要应用字符串,首先先遍历一遍定义的字符串,判断1的个数,再遍历一遍,如果没有11位,输出wrong format,再判断上述的错误情况,然后判奇偶位(
学校学生学号格式定义如下:
2位年级号+2位学院号+2位班级号+2位序号,如19041103,
编写程序处理用全院学生学号连接起来的长字符串,学院编号为20,包括17、18、19、20四个年级,请从字符串中提取特定两个班级202017班、202061班同学的学号后四位输出,输出编号之间用空格分隔,不换行。
注意:需要排除非法输入。
输入格式:
全院学生学号组成的长字符串(学号之间无分隔)
学号格式定义如下:
2位年级号+2位学院号+2位班级号+2位序号,如19041103,
输出格式:
特定两个班级202017班、202061班同学的学号后四位
如:1701 6103 1704
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner input=new Scanner(System.in); int sum=1; String s=input.nextLine(); for(int i=0;i<s.length();i=i+11) { if(s.length()<11) { System.out.print("null data"); } else if(s.charAt(s.length())==0&&s.length()%2==0) { System.out.print("validate error"); } else if(s.charAt(i)==0&&s.charAt(i)!=0&&s.length()>11) { for(int j=i+1;j<i+9;j++) { System.out.println(sum+":"+s.charAt(i)); } } sum++; } } }
*这题和上一题相似,但是要注意错误格式情况。
*题目集3的代码与分析:
定义一个代表一元二次方程ax2+bx+c=0的类QuadraticEquation,其属性为三个系数a、b、c(均为私有属性),类中定义的方法参考main方法中的代码。
*题目已经告诉我们主方法,我们只要写方法和类就行,这题的类图如下:

*这题的我写了一个求方程的类,然后写了7个方法,先写一个方法写入a,b,c.再getA,getB,getC,然后再getroot1,getroot2,最后算出来getDiscriminant():b * b - 4 * a * c
root2 = (-b - Math.sqrt(b * b - 4 * a * c))/(2*a);root1 = (-b + Math.sqrt(b * b - 4 * a * c))/(2*a);。
以下为源码:
import java.util.Scanner; public class Main { public static void main(String[] args){ Scanner input = new Scanner(System.in); double a = Double.parseDouble(input.next()); double b = Double.parseDouble(input.next()); double c = Double.parseDouble(input.next()); if(a == 0){ System.out.println("Wrong Format"); System.exit(0); } //create a QuadraticEquation object QuadraticEquation equation = new QuadraticEquation(a, b, c); //get value of b * b - 4 * a * c double discriminant = equation.getDiscriminant(); System.out.println("a=" + equation.getA() + ",b=" + equation.getB() + ",c=" + equation.getC()+":"); if (discriminant < 0) { System.out.println("The equation has no roots."); } else if (discriminant == 0) { System.out.println("The root is " + String.format("%.2f", equation.getRoot1())); } else // (discriminant >= 0) { System.out.println("The roots are " + String.format("%.2f", equation.getRoot1()) + " and " + String.format("%.2f", equation.getRoot2())); } } } class QuadraticEquation{ private double a; private double b; private double c; public QuadraticEquation(double a, double b, double c) { // TODO 自动生成的构造函数存根 this.a=a; this.b=b; this.c=c; } public double getRoot2() { // TODO 自动生成的方法存根 double root2; root2 = (-b - Math.sqrt(b * b - 4 * a * c))/(2*a); return root2; } public double getRoot1() { // TODO 自动生成的方法存根 double root1; root1 = (-b + Math.sqrt(b * b - 4 * a * c))/(2*a); return root1; } //your code public double getC() { // TODO 自动生成的方法存根 return c; } public double getB() { // TODO 自动生成的方法存根 return b; } public double getA() { // TODO 自动生成的方法存根 return a; } public double getDiscriminant() { // TODO 自动生成的方法存根 return b * b - 4 * a * c; } }
参考题目集二中和日期相关的程序,设计一个类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”格式返回日期值
*这一个题目集,要用类的知识来解决,本题类图如下:

*这题要注意类间的关系,比如判断year是否为闰年的方法要用再用在下面的好几个方法中。检测输入的年、月、日是否合法:要判断闰年2月29号,平年2月28号,1,3,5,7,8,10,12月最大日期为31号,其它月份最大日期为30号。判断year是否为闰年:年份整除以400或年份除以100不等于0,除以4等于0;取得year-month-day的下n天日期,取得year-month-day的前n天日期,判断两个日期是否相等,求当前日期与date之间相差的天数这几个方法与课前训练2中的题目类似,可以借鉴。最后是格式返回日期值,要注意格式。该类的源代码如下:
class DateUtil{ private int year; private int month; private int day; public int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; public DateUtil(DateUtil d){ this.day = d.getDay(); this.month = d.getMonth(); this.year = d.getYear(); int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; } public DateUtil(int ye, int mo, int da){ year = ye; month = mo; day = da; int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; } public void setDay(int day) { this.day = day; } public int getDay() { return day; } public int getMonth() { return month; } public int getYear() { return year; } public void setMonth(int month) { this.month = month; } public void setYear(int year) { this.year = year; } public boolean checkInputValidity(){ int[] arr={31,28,31,30,31,30,31,31,30,31,30,31}; if(this.isLeapYear(this.getYear())) { arr[1]=29; } if(year < 1820 || year > 2020||month < 1 || month > 12|| day<1 || day>arr[month-1]) return false; else return true; } public boolean isLeapYear(int year){ if(year%400==0||(year%4==0&&year%100!=0)) return true; else return false; } public DateUtil getNextNDays(int n){ while(n>365){ if(this.isLeapYear(year)&&month <= 2){ if(month==2&&day==29){ day=1; month=3; } else if(month==2&&day>29) { System.out.println("Wrong Format"); System.exit(0); } year++; n=n-366; } else if(this.isLeapYear(year+1)&&month>2){ year++; n=n-366; } else{ year++; n=n-365; } } for (int i=0;i<n;i++) { day++; if(this.isLeapYear(year)&&month==2){ if(day>29){ month++; day=1; } } else if(day>a[month]){ month++; day=1; if(month>12){ month=1; year++; } } } return this; } public DateUtil getPreviousNDays(int n){ DateUtil da = new DateUtil(this); while(n > 365){ if(da.isLeapYear(da.getYear()) && da.getMonth() > 2||da.isLeapYear(da.getYear() - 1) && da.getMonth() <= 2){ n = n - 366; da.setYear(da.getYear() - 1); } else{ n = n - 365; da.setYear(da.getYear() - 1); } } for(int i = 0; i < n; i++){ da.setDay(da.getDay() - 1); if(da.getDay() <= 0){ da.setMonth(da.getMonth() - 1); if(da.getMonth() <= 0){ da.setMonth(12); da.setYear(da.getYear() - 1); } if(isLeapYear(da.getYear()) && da.getMonth() == 2) da.setDay(29); else da.setDay(da.a[da.getMonth()]); } } return da; } public boolean compareDates(DateUtil date){ if(this.year > date.getYear()) return true; else if(this.year == date.getYear() && this.month > date.getMonth()) return true; else if(this.year == date.getYear() && this.month == date.getMonth() && this.day > date.getDay()) return true; return false; } public boolean equalTwoDates(DateUtil date){ if(this.year != date.getYear()) return false; else if(this.day != date.getDay()) return false; else if(this.month != date.getMonth()) return false; else return true; } public int getDaysofDates(DateUtil date){ int sum = 0; boolean b = this.compareDates(date); DateUtil da = new DateUtil(this); if(b){ while(da.getYear() - date.getYear() >= 2){ if(da.isLeapYear(da.getYear()) && da.getMonth() > 2||da.isLeapYear(da.getYear() - 1) && da.getMonth() <= 2) sum = sum + 366; else sum = sum + 365; da.setYear(da.getYear() - 1); } while(true){ if(da.equalTwoDates(date)) break; sum++; da.setDay(da.getDay()-1); if(da.getDay() <= 0){ da.setMonth(da.getMonth() - 1); if(da.getMonth() <= 0){ da.setMonth(12); da.setYear(da.getYear() - 1); } if(isLeapYear(da.getYear()) && da.getMonth()==2) da.setDay(29); else da.setDay(da.a[da.getMonth()]); } } } else{ while(date.getYear()-da.getYear()>= 2){ if(da.isLeapYear(da.getYear()) && da.getMonth() <= 2) sum = sum + 366; else if(da.isLeapYear(da.getYear() + 1) && da.getMonth() > 2) sum = sum + 366; else sum = sum + 365; da.setYear(da.getYear() + 1); } while(true){ if(da.equalTwoDates(date)) break; sum++; da.setDay(da.getDay() + 1); if(isLeapYear(da.getYear()) && da.getMonth() == 2){ if(da.getDay() > 29){ da.setMonth(da.getMonth() + 1); da.setDay(1); } } else if(da.getDay()>da.a[da.getMonth()]){ da.setMonth(da.getMonth() + 1); da.setDay(1); if(da.getMonth() > 12){ da.setMonth(1); da.setYear(da.getYear() + 1); } } } } return sum; } public String showDate(){ return year + "-" + month + "-" + day; } }
参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] ,
应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
*这题考察类的聚合,是第一题的升级版,将7-1的一个类中的方法全部写成类,类图如下:

*这题我们要按照类图严格写代码,要注意每个类的类名,类里的变量数目,类中方法的类型,以及方法的关系和方法的调用。源代码如下:
class Day{ private int day; public Day() { } public Day(int day) { this.day=day; } public int getValue() { return day; } public void setValue(int day) { this.day=day; } public void dayIncrement() { day++; } public void dayReduction() { day--; } } class Year{ private int year; private int day; private int month; public Year() { } public Year(int year) { this.year=year; } public int getValue() { return year; } public void setValue(int day) { this.year=year; } public static boolean isLeapYear(int year){ if(year%400==0||(year%4==0&&year%100!=0)) return true; else return false; } public boolean validity(){ int[] arr={31,28,31,30,31,30,31,31,30,31,30,31}; if(this.isLeapYear(year)) { arr[1]=29; } if(year<1820||year>2020||month<1||month>12||day<1||day>arr[month-1]) return false; else return true; } public void yearIncrement() { year++; } public void yearReduction() { year--; } } class Month{ private int month; private int year; public Month() { } public Month(int month) { this.month=month; } public int getValue() { return month; } public void setValue(int day) { this.month=month; } public void resetMin() { month=1; } public void resetMax(){ month=12; } public boolean validity(){ int[] arr={31,28,31,30,31,30,31,31,30,31,30,31}; if(Year.isLeapYear(year)&&arr[1]==29) { return true; } else if(!Year.isLeapYear(year)&&arr[1]==29) { return false; } else if(Year.isLeapYear(year)&&arr[1]==28) { return false; } else if(Year.isLeapYear(year)&&arr[1]==28) { return false; } else return true; } public void monthIncrement() { month++; } public void monthReduction() { month--; } } class DateUtil{ private int year; private int month; private int day; public int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; public DateUtil(DateUtil d){ this.day = d.getDay(); this.month = d.getMonth(); this.year = d.getYear(); int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; } public DateUtil(int ye, int mo, int da){ year = ye; month = mo; day = da; int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; } public void setDay(int day) { this.day = day; } public int getDay() { return day; } public int getMonth() { return month; } public int getYear() { return year; } public void setMonth(int month) { this.month = month; } public void setYear(int year) { this.year = year; } public boolean checkInputValidity(){ int[] arr={31,28,31,30,31,30,31,31,30,31,30,31}; if(this.isLeapYear(this.getYear())) { arr[1]=29; } if(year < 1900 || year > 2050||month < 1 || month > 12|| day<1 || day>arr[month-1]) return false; else return true; } public boolean isLeapYear(int year){ if(year%400==0||(year%4==0&&year%100!=0)) return true; else return false; } public DateUtil getNextNDays(int n){ while(n>365){ if(this.isLeapYear(year)&&month <= 2){ if(month==2&&day==29){ day=1; month=3; } else if(month==2&&day>29) { System.out.println("Wrong Format"); System.exit(0); } year++; n=n-366; } else if(this.isLeapYear(year+1)&&month>2){ year++; n=n-366; } else{ year++; n=n-365; } } for (int i=0;i<n;i++) { day++; if(this.isLeapYear(year)&&month==2){ if(day>29){ month++; day=1; } } else if(day>a[month]){ month++; day=1; if(month>12){ month=1; year++; } } } return this; } public DateUtil getPreviousNDays(int n){ DateUtil da = new DateUtil(this); while(n > 365){ if(da.isLeapYear(da.getYear()) && da.getMonth() > 2||da.isLeapYear(da.getYear() - 1) && da.getMonth() <= 2){ n = n - 366; da.setYear(da.getYear() - 1); } else{ n = n - 365; da.setYear(da.getYear() - 1); } } for(int i = 0; i < n; i++){ da.setDay(da.getDay() - 1); if(da.getDay() <= 0){ da.setMonth(da.getMonth() - 1); if(da.getMonth() <= 0){ da.setMonth(12); da.setYear(da.getYear() - 1); } if(isLeapYear(da.getYear()) && da.getMonth() == 2) da.setDay(29); else da.setDay(da.a[da.getMonth()]); } } return da; } public boolean compareDates(DateUtil date){ if(this.year > date.getYear()) return true; else if(this.year == date.getYear() && this.month > date.getMonth()) return true; else if(this.year == date.getYear() && this.month == date.getMonth() && this.day > date.getDay()) return true; return false; } public boolean equalTwoDates(DateUtil date){ if(this.year != date.getYear()) return false; else if(this.day != date.getDay()) return false; else if(this.month != date.getMonth()) return false; else return true; } public int getDaysofDates(DateUtil date){ int sum = 0; boolean b = this.compareDates(date); DateUtil da = new DateUtil(this); if(b){ while(da.getYear() - date.getYear() >= 2){ if(da.isLeapYear(da.getYear()) && da.getMonth() > 2||da.isLeapYear(da.getYear() - 1) && da.getMonth() <= 2) sum = sum + 366; else sum = sum + 365; da.setYear(da.getYear() - 1); } while(true){ if(da.equalTwoDates(date)) break; sum++; da.setDay(da.getDay()-1); if(da.getDay() <= 0){ da.setMonth(da.getMonth() - 1); if(da.getMonth() <= 0){ da.setMonth(12); da.setYear(da.getYear() - 1); } if(isLeapYear(da.getYear()) && da.getMonth()==2) da.setDay(29); else da.setDay(da.a[da.getMonth()]); } } } else{ while(date.getYear()-da.getYear()>= 2){ if(da.isLeapYear(da.getYear()) && da.getMonth() <= 2) sum = sum + 366; else if(da.isLeapYear(da.getYear() + 1) && da.getMonth() > 2) sum = sum + 366; else sum = sum + 365; da.setYear(da.getYear() + 1); } while(true){ if(da.equalTwoDates(date)) break; sum++; da.setDay(da.getDay() + 1); if(isLeapYear(da.getYear()) && da.getMonth() == 2){ if(da.getDay() > 29){ da.setMonth(da.getMonth() + 1); da.setDay(1); } } else if(da.getDay()>da.a[da.getMonth()]){ da.setMonth(da.getMonth() + 1); da.setDay(1); if(da.getMonth() > 12){ da.setMonth(1); da.setYear(da.getYear() + 1); } } } } return sum; } public String showDate(){ return year + "-" + month + "-" + day; } }
三·踩坑心得:
问题1:长度质量计量单位换算小数点问题,错误源码与结果:
double bang,arce;
bang=kg/0.45359237;
arce=m/0.0254;
System.out.print(bang+" "+arce);

解决方法:强制转化变量的类型从double转为float,正确结果:
float m = input.nextFloat(); float bang,arce; bang=(float)(kg/0.45359237); arce=(float)(m/0.0254);

心得:输出数据保留位数错误,考虑强制转换。
问题2:字符串遍历的时候,i<=s.length(),超界了,导致无法输出。
for(i=0;i<=s.length();i++) { if((s.charAt(i)=='-')&&(s.charAt(i+1)=='1')) { break; } }

解决方法:将“=”去掉。

心得:注意字符串像数组一样,从0开始。
问题3:判断直角三角形时,不能直接两边直接等于第3边,要考虑误差。
else if(a==b||a==c||b==c)
{
if(a*a+b*b==c*c||a*a+c*c==b*b||b*b+c*c==a*a)
{
System.out.println("Isosceles right-angled triangle" );
}
解决方法:改为如下:
else if(a==b||a==c||b==c) { if(a*a+b*b-c*c<0.1||a*a+c*c-b*b<0.1||b*b+c*c-a*a<0.1) { System.out.println("Isosceles right-angled triangle" ); }
心得:要注意java的数据误差,Java的等于号精度问题。
问题4:英文字母转换成字母表序号时,出现错误。


解决方法:改为如下:
if(s.charAt(i) >= 'A'&&s.charAt(i)<= 'Z') { k= s.charAt(i) - 64; System.out.print(k); } else if (s.charAt(i) >= 'a'&&s.charAt(i) <= 'z') { k= s.charAt(i) - 96;

心得:要注意ASCII表的数据。
问题5:字符串超界。

else if(s.charAt(s.length())==0) { System.out.print("validate error"); }
解决方法:可以重启编译器,或者重新编译运行程序,或者检查字符串,数组有没有超界。
else if(s.charAt(s.length())==0&&s.length()%2==0) { System.out.print("validate error"); }
心得:要注意数组,字符串的基本语法和用法。
问题6:题目集3,第2题运行超时,正常值测试,下n天:整型数最大值测试,样例如下。
public DateUtil getNextNDays(int n){ while(n>365){ if(this.isLeapYear(year)&&month <= 2){ if(month==2&&day==29){ day=1; month=3; year++; n=n-366; } else if(this.isLeapYear(year+1)&&month>2){ year++; n=n-366; } else{ year++; n=n-365; } } for (int i=0;i<n;i++) { day++; if(this.isLeapYear(year)&&month==2){ if(day>29){ month++; day=1; } } else if(day>a[month]){ month++; day=1; if(month>12){ month=1; year++; } } } } return this; }

解决方法:这题我不知道怎么对原来的算法进行修改,于是我换了一个算法,最后成功了。
public DateUtil getNextNDays(int n){ while(n>365){ if(this.isLeapYear(year)&&month <= 2){ if(month==2&&day==29){ day=1; month=3; } else if(month==2&&day>29) { System.out.println("Wrong Format"); System.exit(0); } year++; n=n-366; } else if(this.isLeapYear(year+1)&&month>2){ year++; n=n-366; } else{ year++; n=n-365; } } for (int i=0;i<n;i++) { day++; if(this.isLeapYear(year)&&month==2){ if(day>29){ month++; day=1; } } else if(day>a[month]){ month++; day=1; if(month>12){ month=1; year++; } } } return this; }

public DateUtil getNextNDays(int n){ while(n>365){ if(this.isLeapYear(year)&&month <= 2){ if(month==2&&day==29){ day=1; month=3; } else if(month==2&&day>29) { System.out.println("Wrong Format"); System.exit(0); } year++; n=n-366; } else if(this.isLeapYear(year+1)&&month>2){ year++; n=n-366; } else{ year++; n=n-365; } } for (int i=0;i<n;i++) { day++; if(this.isLeapYear(year)&&month==2){ if(day>29){ month++; day=1; } } else if(day>a[month]){ month++; day=1; if(month>12){ month=1; year++; } } } return this; }
心得:如果遇到无法改进的算法,那就换一个算法。
问题7:题目集3第3题,年,月,日,超界。

public DateUtil getNextNDays(int n){ while(n>365){ if(this.isLeapYear(year)&&month <= 2){ if(month==2&&day==29){ day=1; month=3; } year++; n=n-366; } else if(this.isLeapYear(year+1)&&month>2){ year++; n=n-366; } else{ year++; n=n-365; } } for (int i=0;i<n;i++) { day++; if(this.isLeapYear(year)&&month==2){ if(day>29){ month++; day=1; } } else if(day>a[month]){ month++; day=1; if(month>12){ month=1; year++; } } } return this; } public DateUtil getPreviousNDays(int n){ DateUtil da = new DateUtil(this); while(n > 365){ if(da.isLeapYear(da.getYear()) && da.getMonth() > 2||da.isLeapYear(da.getYear() - 1) && da.getMonth() <= 2){ n = n - 366; da.setYear(da.getYear() - 1); } else{ n = n - 365; da.setYear(da.getYear() - 1); } } for(int i = 0; i < n; i++){ da.setDay(da.getDay() - 1); if(da.getDay() <= 0){ da.setMonth(da.getMonth() - 1); if(da.getMonth() <= 0){ da.setMonth(12); da.setYear(da.getYear() - 1); } if(isLeapYear(da.getYear()) && da.getMonth() == 2) da.setDay(29); else da.setDay(da.a[da.getMonth()]); } } return da; } public boolean compareDates(DateUtil date){ if(this.year > date.getYear()) return true; else if(this.year == date.getYear() && this.month > date.getMonth()) return true; else if(this.year == date.getYear() && this.month == date.getMonth() && this.day > date.getDay()) return true; return false; }
解决方法:这题我进行了年,月,日的测试,发现是下n天过了一年,一月时出错了,对症下药,进行修改。

public DateUtil getNextNDays(int n){ while(n>365){ if(this.isLeapYear(year)&&month <= 2){ if(month==2&&day==29){ day=1; month=3; } else if(month==2&&day>29) { System.out.println("Wrong Format"); System.exit(0); } year++; n=n-366; } else if(this.isLeapYear(year+1)&&month>2){ year++; n=n-366; } else{ year++; n=n-365; } } for (int i=0;i<n;i++) { day++; if(this.isLeapYear(year)&&month==2){ if(day>29){ month++; day=1; } } else if(day>a[month]){ month++; day=1; if(month>12){ month=1; year++; } } } return this; } public DateUtil getPreviousNDays(int n){ DateUtil da = new DateUtil(this); while(n > 365){ if(da.isLeapYear(da.getYear()) && da.getMonth() > 2||da.isLeapYear(da.getYear() - 1) && da.getMonth() <= 2){ n = n - 366; da.setYear(da.getYear() - 1); } else{ n = n - 365; da.setYear(da.getYear() - 1); } } for(int i = 0; i < n; i++){ da.setDay(da.getDay() - 1); if(da.getDay() <= 0){ da.setMonth(da.getMonth() - 1); if(da.getMonth() <= 0){ da.setMonth(12); da.setYear(da.getYear() - 1); } if(isLeapYear(da.getYear()) && da.getMonth() == 2) da.setDay(29); else da.setDay(da.a[da.getMonth()]); } } return da; }
四·改进建议:
1.题目集1:7-7
if( a < 1 || a >200 || b > 200 || b < 1 || c < 1 || c > 200 ) { System.out.println("Wrong Format"); } else if( a + b <= c || a + c <= b || c + b <= a) { System.out.println("Not a triangle"); } else if( a == b && a == c && b == c ) { System.out.println("Equilateral triangle" ); } else if(a==b||a==c||b==c) { if(a*a+b*b-c*c<0.1||a*a+c*c-b*b<0.1||b*b+c*c-a*a<0.1) { System.out.println("Isosceles right-angled triangle" ); } else { System.out.println("Isosceles triangle" ); } } else if((a!=b&&a*a+b*b==c*c)||(a!=c&&a*a+c*c==b*b)||(b!=c&&b*b+c*c==a*a)) { System.out.println("Right-angled triangle" ); } else { System.out.println("General triangle" ); }
*这个题目可以把if语句与switch语句交换使用,效果一样,但是代码的行数不同,switch语句比较少。
题目集3:7-1
public double getRoot2() { // TODO 自动生成的方法存根 double root2; root2 = (-b - Math.sqrt(b * b - 4 * a * c))/(2*a); return root2; } public double getRoot1() { // TODO 自动生成的方法存根 double root1; root1 = (-b + Math.sqrt(b * b - 4 * a * c))/(2*a); return root1; } //your code
*这部分代码可以由下面的代码替换:
public double getRoot2() { return (-b - Math.sqrt(b * b - 4 * a * c))/(2*a); } public double getRoot1() { return (-b + Math.sqrt(b * b - 4 * a * c))/(2*a); }
这样更简洁明了。
*面向对象能实现代码很好的复用性,技巧性也不是很强,我们学习中要深刻的理解。这对以后的编程大有益处。
五·总结:
*经过前三次作业的学习,我认为我主要还是提升了主在各种数据的处理方面,对类似c语言的语法的题目编码能力,对类和对象的理解,逻辑思维能力。第一次PTA作业主要为基本数据的运算和简单的循环和选择,字符串处理,这三大处理;第二次的大作业是字符串的处理这个方面,但是难度比第一次高,对基本的逻辑思维算法能力有一定的考察;第三次的大作业就不再是前两次的简单的数据处理了,最主要考察的还是对不同月,年份的思考,需要考虑不同的方面,考察了我们对面向对象的思考了,不再只是写在一个主类了,不只是考察我们的基本写一些代码的问题了,更多的是考察我们对面向对象这一实质的思考与研究,利用数据的私有和不同类之间的关联。
*说实话一个礼拜的时间是够写的,但是一堆的让人崩溃的绿色点(PTA测试点不通过的情况)还是很让人崩溃。从第3次作业明显难度就上升了好多,经过询问多次同学才最终解决,太难了,以后一定更加努力。
*希望老师能开放多一些测试点供我们学习,没有在规定时间写完也能出一下不计分的原题,可以让没有及时解决问题的同学继续尝试解决,老师也可以讲一讲PTA的题目(在规定时间之后)。
浙公网安备 33010602011771号