BLOG-1(pta前三次java题目集分析)
BLOG-1 目录
- BLOG-1 目录
- (1)前言
- 1. 知识点
- 2. 题量
- 3. 难度
- (2)设计与分析
- 1. 题目集2的7-2
- 2. 题目集3的7-1
- 3. 题目集3的7-2
- 4. 题目集3的7-3
- (3)踩坑心得
- 1. 题目集2的7-2:
- 2. 题目集3的7-1:
- 3. 题目集3的7-2:
- 4. 题目集3的7-3:
- (4)改进建议
- (5)总结
- 1. 学到的知识
- 2. 需要进一步学习及研究的地方
- 3. 对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见:
(1)前言
1. 知识点
- 第一次题目集:基本数据类型的运用、不同变量类型的定义和赋值、操作符的简单运用,以及字符串的初步认识。
- 第二次题目集:字母-数字转换、串口字符解析、String的格式判断与内容提取。
- 第三次题目集:定义类解决复杂问题,认识并尝试类的不同聚合的方式。
2. 题量
- 第一次题目集:一共9道题目。
- 第二次题目集:一共3道题目。
- 第三次题目集:一共4道题目。
3. 难度
- 第一次题目集:难度较小。
- 第二次题目集:难度适中。
- 第三次题目集:难度较大。
(2)设计与分析
1. 题目集2的7-2
- 源码:
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner input = new Scanner (System.in);
String a=input.nextLine();
int n=a.length();
if(n<11){
System.out.print ("null data");
return;
}
int t=0;
for(int i=0;i<n;i++){
if(a.charAt(i)=='1'){
t++;
}
}
if(t==n){
System.out.print ("null data");
return;
}
t=1;
int k=0;
for(int i=0;i<n;i++){
if(a.charAt (i)=='0'&&i+10<n){
for(int j=i+1;j<=i+8;j++){
if(a.charAt (j)=='1'){
k++;
}
}
if(k%2==0) {
if (a.charAt (i + 9) == '1' && a.charAt (i + 10) == '1'&&i+10<n) {
System.out.println (t + ":" + a.charAt (i + 1) + "" + a.charAt (i + 2) + a.charAt (i + 3) + "" + a.charAt (i + 4) + "" + a.charAt (i + 5) + "" + a.charAt (i + 6) + "" + a.charAt (i + 7) + "" + a.charAt (i + 8));
t++;
i+=10;
} else if (a.charAt (i + 9) == '0' && a.charAt (i + 10) == '1'&&i+10<n) {
System.out.println (t + ":" + "parity check error");
t++;
i+=10;
} else if (a.charAt (i + 9) == '1' && a.charAt (i + 10) == '0'&&i+10<n) {
System.out.println (t + ":" + "validate error");
t++;
i+=10;
} else if (a.charAt (i + 9) == '0' && a.charAt (i + 10) == '0'&&i+10<n) {
System.out.println (t + ":" + "validate error");
t++;
i+=10;
}
}
else{
if (a.charAt (i + 9) == '0' && a.charAt (i + 10) == '1'&&i+10<n) {
System.out.println (t + ":" + a.charAt (i + 1) + "" + a.charAt (i + 2) + a.charAt (i + 3) + "" + a.charAt (i + 4) + "" + a.charAt (i + 5) + "" + a.charAt (i + 6) + "" + a.charAt (i + 7) + "" + a.charAt (i + 8));
t++;
i+=10;
}else if (a.charAt (i + 9) == '1' && a.charAt (i + 10) == '1'&&i+10<n) {
System.out.println (t + ":" + "parity check error");
t++;
i+=10;
} else if (a.charAt (i + 9) == '0' && a.charAt (i + 10) == '0'&&i+10<n) {
System.out.println (t + ":" + "validate error");
t++;
i+=10;
} else if (a.charAt (i + 9) == '1' && a.charAt (i + 10) == '0'&&i+10<n) {
System.out.println (t + ":" + "validate error");
t++;
i+=10;
}
}
}
k=0;
}
}
}
- 思路分析:
①采用nextLine()获取数据;
②采用for循环遍历验证数据合法性;
③输出数据对应结果; - 对源代码的分析:
①先用nextLine()读取数据;
②然后for循环遍历,将错误数据情况全用if进行判断;
③输出数据对应if的结果;
2. 题目集3的7-1
- 源码:
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
{
System.out.println("The roots are " +
String.format("%.2f", equation.getRoot1())
+ " and " + String.format("%.2f", equation.getRoot2()));
}
}
}
class QuadraticEquation{
double a,b,c;
public QuadraticEquation(double a, double b, double c) {
this.a=a;
this.b=b;
this.c=c;
}
public double getDiscriminant() {
return b * b - 4 * a * c;
}
public double getRoot1() {
double x=(-b+Math.sqrt ( b * b - 4 * a * c))/(2*a);
return x;
}
public double getRoot2() {
double x=(-b-Math.sqrt ( b * b - 4 * a * c))/(2*a);
return x;
}
public double getA() {
return a;
}
public double getB() {
return b;
}
public double getC() {
return c;
}
}
- 思路分析:
①依题目要求建立QuadraticEquation类求根;
②根据求根公式判断并计算一元二次方程的根;
③return相应的结果; - 对源代码的分析:
- ①首先在QuadraticEquation类定义并初始化方程系数的值;
- ②然后分别创建判别根合法性方法及求根方法;
- ③计算方程的根并return给main;
- ④powerDesigner的相应类图:
3. 题目集3的7-2
- 源码:
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(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");
System.out.println(date.getNextNDays(m).showDate());
} else if (choice == 2) { // test getPreviousNDays method
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) { //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 " + 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{
int year,month,day;
public DateUtil(int year, int month, int day) {
this.year=year;
this.month=month;
this.day=day;
}
public boolean checkInputValidity(){
return year >= 1820 && year <= 2020 && month >= 1 && month <= 12 && day >= 1 && day <= 31;
}//检测输入的年、月、日是否合法
public boolean isLeapYear(int year){
return year % 400 == 0 || year % 100 != 0 && year % 4 == 0;
}//判断year是否为闰年
public DateUtil getNextNDays(int n){
if(n==0)
return new DateUtil(year, month, day);
int k = 0;
int[] a = {0,31,28,31,30,31,30,31,31,30,31,30,31};
for (int i = this.month+1; i <=12; i++) {
k+=a[i];
}
k+=a[this.month]-this.day;
if(isLeapYear(this.year)&&this.month<=2)
k++;
int year=0,month,day;
if(k>n){
int dayl = a[this.month];
if (isLeapYear(this.year)&&this.month==2) {
dayl++;
}
dayl-=this.day;
if(dayl>=n){
month=this.month;
day=n+this.day;
}
else{
n-=dayl;
month=this.month+1;
int j=month;
if (n - a[k] > 0 && j <= 12) {
do {
n -= a[k];
month++;
j++;
} while (n - a[k] > 0 && j <= 12);
}
day=n;
}
}
else{
n-=k;
year = this.year+1;
int y=365;
if(isLeapYear (year)){
y++;
}
if (n - y > 0) {
do {
n -= y;
year++;
y = 365;
if (isLeapYear (year))
y++;
} while (n - y > 0);
}
int j=1;
if (n - a[j] > 0) {
do {
n -= a[j];
j++;
} while (n - a[j] > 0);
}
month=j;
day=n;
}
return new DateUtil(year, month, day);
}//取得year-month-day的下n天日期
public DateUtil getPreviousNDays(int n){
int k = 0;
int[] a = {0,31,28,31,30,31,30,31,31,30,31,30,31};
for (int i = this.month+1; i <=12; i++) {
k+=a[i];
}
k+=a[this.month]-this.day;
if(isLeapYear(this.year)&&this.month<=2)
k++;
int year, month, day;
int r = 365-k;
if (isLeapYear(this.year)) {
r++;
}
if (r>n) {//本年
year=this.year;
int dayl=this.day;//本月剩余的日期
if (dayl>n) { //本月
month = this.month;
day = dayl-n;
}
else{ //其他月
n-=dayl;
month = this.month-1;
if (month==0) {
month = 12;
year=this.year-1;
}
int j = month;
if (n - a[j] > 0) {
do {
n -= a[j];
month--;
j--;
} while (n - a[j] > 0);
}
day = a[j]-n;
if (isLeapYear(year)&&month==2) {
day++;
}
}
}
else {
n-=r;
year = this.year-1;
int y = 365;
if (isLeapYear(year)) {
y++;
}
if (n - y > 0) {
do {
n -= y;
year--;
y = 365;
if (isLeapYear (year))
y++;
} while (n - y > 0);
}
int j = 12;
if (n - a[j] > 0) {
do {
n -= a[j];
j--;
} while (n - a[j] > 0);
}
month = j;
day = a[j]-n;
if (isLeapYear(year)&&month==2) {
day++;
}
}
return new DateUtil(year, month, day);
}//取得year-month-day的前n天日期
public boolean compareDates(DateUtil date){
if (date.year<this.year) {
return false;
}
else if (date.year==this.year&&date.month<this.month) {
return false;
}
if (date.year==this.year&&date.month==this.month&&date.day<this.day) {
return false;
}
return true;
}//比较当前日期与date的大小(先后)
public boolean equalTwoDates(DateUtil date){
return year == date.year && month == date.month && day == date.day;
}//判断两个日期是否相等
public int getDaysofDates(DateUtil date){
int[] a;
a = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int days=0;
if(date.year<year) {
for (int i = year - 1; i > date.year; i--)
if (isLeapYear(i)) {
days += 366;
} else {
days += 365;
}
if (isLeapYear(year)) a[2] = 29;
for (int i = 1; i < month; i++) days += a[i];
days += day;
a[2]=28;
if (isLeapYear(date.year)) a[2] = 29;
for (int i = 12; i > date.month; i--) days += a[i];
days += a[date.month]-date.day;
return days;
}
else if(date.year>year){
for (int i = date.year - 1; i > year; i--)
if (isLeapYear(i)) {
days += 366;
} else {
days += 365;
}
if (isLeapYear(date.year)) a[2] = 29;
for (int i = 1; i < date.month; i++) days += a[i];
days += date.day;
a[2]=28;
if (isLeapYear(year)) a[2] = 29;
for (int i = 12; i > month; i--) days += a[i];
days += a[month]-day;
return days;
}
else{
if(date.month > month){
if (isLeapYear(date.year)) a[2] = 29;
for (int i = month; i < date.month; i++) days += a[i];
days += date.day;
days -= day;
return days;
}
else if(month>date.month){
if (isLeapYear(date.year)) a[2] = 29;
for (int i = date.month; i < month; i++) days += a[i];
days += day;
days -= date.day;
return days;
}
else {
return Math.abs (date.day-day);
}
}
}//求当前日期与date之间相差的天数
public String showDate(){
return this.year + "-" + this.month + "-" + this.day;
}//以“year-month-day”格式返回日期值
public int getYear() {
return year;
}
public int getMonth() {
return month;
}
public int getDay() {
return day;
}
}
- 思路分析:
①根据题目要求建立DateUtil类并构建各个方法;
③return相应的结果; - 对源代码的分析:
- ①首先在DateUtil类定义并初始化year,month,day的值;
- ②然后分别建立求前n天的方法getPreviousNDays,求当前日期与date之间相差的天数的方法getDaysofDates,取得year-month-day的下n天日期的方法getNextNDays;
- ③getPreviousNDays:循环从总前n天的n中减去当前月的天数且对year,month,day实时改变,同时判断是否闰月,当n为0是即为前n天的日期。
- getNextNDays与getPreviousNDays同理。
- getPreviousNDays:将两个日期的day单独相加,然后对其余月份直接加;
- ④计算相应的结果并return给main;
- ⑤powerDesigner的相应类图:
4. 题目集3的7-3
- 源码:
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.println(date.getNextNDays(m).showDate());
} else if (choice == 2) { // test getPreviousNDays method
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.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(fromDate.getDaysofDates(toDate));
} else {
System.out.println("Wrong Format");
System.exit(0);
}
}
else{
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class DateUtil {
private final int year,month,day;
private final int [] Month1 = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
private final int[] Month2 ={0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
public DateUtil(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
private int getDay(int year, int month) {
int days;
days = Month1[month];
if (isLeapYear(year) && month == 2) {
days = 29;
}
return days;
}
public boolean checkInputValidity(){
if(isLeapYear(year)) {
return year >= 1900 && year <= 2050 && month >= 1 && month <= 12 && day >= 1 && day <= Month2[month];
}
else{
return year >= 1900 && year <= 2050 && month >= 1 && month <= 12 && day >= 1 && day <= Month1[month];
}
}//检测输入的年、月、日是否合法
public boolean isLeapYear(int year)//判断year是否为闰年
{
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}
public DateUtil getNextNDays(int n)//取得year-month-day的下n天日期
{
int year = this.year;
int month = this.month;
int day = this.day;
int i = 0;
if (i < n) {
do {
day++;
int t = getDay (year, month);
if (day > t) {
month++;
day = 1;
if (month > 12) {
year++;
month = 1;
}
}
i++;
} while (i < n);
return new DateUtil(year, month, day);
} else {
return new DateUtil(year, month, day);
}
}
public DateUtil getPreviousNDays(int n)//取得year-month-day的前n天日期
{
int year = this.year;
int month = this.month;
int day = this.day;
int i = 0;
if (i < n) {
do {
day--;
if (day < 1) {
do {
month--;
if (month < 1) {
month = 12;
year--;
}
day += getDay (year, month);
} while (day < 1);
}
i++;
} while (i < n);
return new DateUtil(year, month, day);
} else {
return new DateUtil(year, month, day);
}
}
public boolean compareDates(DateUtil date)//比较当前日期与date的大小(先后)
{
if (this.year > date.year) return true;
if (this.year == date.year) {
if (this.month > date.month) return true;
if (this.month == date.month) {
return this.day >= date.day;
}
}
return false;
}
public boolean equalTwoDates(DateUtil date)//判断两个日期是否相等
{
if (date != null)
return year == date.year && month == date.month && day == date.day;
else
return false;
}
public int getDaysofDates(DateUtil date)//求当前日期与date之间相差的天数
{
int[] a;
a = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int days=0;
if(date.year<year) {
for (int i = year - 1; i > date.year; i--)
if (isLeapYear(i)) {
days += 366;
} else {
days += 365;
}
if (isLeapYear(year)) a[2] = 29;
for (int i = 1; i < month; i++) days += a[i];
days += day;
a[2]=28;
if (isLeapYear(date.year)) a[2] = 29;
for (int i = 12; i > date.month; i--) days += a[i];
days += a[date.month]-date.day;
return days;
}
else if(date.year>year){
for (int i = date.year - 1; i > year; i--)
if (isLeapYear(i)) {
days += 366;
} else {
days += 365;
}
if (isLeapYear(date.year)) a[2] = 29;
for (int i = 1; i < date.month; i++) days += a[i];
days += date.day;
a[2]=28;
if (isLeapYear(year)) a[2] = 29;
for (int i = 12; i > month; i--) days += a[i];
days += a[month]-day;
return days;
}
else{
if(date.month > month){
if (isLeapYear(date.year)) a[2] = 29;
for (int i = month; i < date.month; i++) days += a[i];
days += date.day;
days -= day;
return days;
}
else if(month>date.month){
if (isLeapYear(date.year)) a[2] = 29;
for (int i = date.month; i < month; i++) days += a[i];
days += day;
days -= date.day;
return days;
}
else {
return Math.abs (date.day-day);
}
}
}
public String showDate()//以“year-month-day”格式返回日期值
{
return year + "-" + month + "-" + day;
}
public int getYear() {
return year;
}
public int getMonth() {
return month;
}
public int getDay() {
return day;
}
}
- 思路分析:
①依题目要求建立DateUtil类、Year类、Month类、Day类;
②将类间关系调整为题目所诉; - 对源代码的分析:
- ①在DateUtil类只能调用Day类的方法,Day类只能调用Month类的方法,Month类只能调用Year类的方法;
- ②在算后n天时,day在计算中只能一天一天增加,当day突破对应month的最大天数,则day=1,month++,当month突破12时month=1,year++,同理求出前n天;
- ③计算并return对应结果给main;
- ④powerDesigner的相应类图:
(3)踩坑心得
1. 题目集2的7-2:
- 题目模拟的串口接收处理程序有效数据是8位,写代码时未对每一段串口数据判断,导致小于8位的串口数据也输出了出来。
2. 题目集3的7-1:
- 参数全为double型,防止运算精度缺失。
3. 题目集3的7-2:
- 对每个月的最后一天,每年的最后一月,闰年2月的最后一天都要单独讨论。
- 对整形最大值进行化小后运算,防止爆int。
4. 题目集3的7-3:
- 对每个月的最后一天,每年的最后一月,闰年2月的最后一天都要单独讨论。
- 对整形最大值进行化小后运算,防止爆int。
- 日期越界讨论。
(4)改进建议
我觉得最需要改进的是题目集3的7-3:
本题源码的类没有满足题目要求的类间关系,只是单纯的仿照前一题仿写。代码在上文给出,自我感觉十分糟糕。对此我有以下修改方案:
- 重新将类拆分,严格按照题目给出的类和方法重新构建;
- 严格按照题目给出类间关系进行方法调用。
(5)总结
对本阶段三次题目集的综合性总结,学到了什么,哪些地方需要进一步学习及研究,对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见:
1. 学到的知识
- 基本数据类型的运用、不同变量类型的定义和赋值、操作符的简单运用,以及字符串的初步认识。
- 字母-数字转换、串口字符解析、String的格式判断与内容提取。
- 定义类解决复杂问题,认识并学会类的不同聚合方式。
2. 需要进一步学习及研究的地方
- 我认为应该要重新学习构建类间关系的相关知识,多学习一些java各种语法的基本原理。
- 熟练掌握构造函数的基本运用
3. 对教师、课程、作业、实验、课上及课下组织方式等方面的改进建议及意见:
- 老师发送的PTA作业有一些的题目测试点过于***钻,而样例和题目信息中又未给出相应提示,导致难以发现。
- 希望PTA作业能够在一些难度较大的题目集后面能够再次发布补题集,让并没有满分的同学能够再次练习测试。