PTA前三次作业总结
前言
第一次作业
第一次作业比较简单,主要是练习一些java的基本语法,例如if,switch,while等早在之前c学过的语法的使用,程序也基本只需要一个main就可以完成,题量虽然较多,但做完所需时间不长。
第二次作业
第二次作业则是第一次作业的进阶版,较第一次作业多了一些对java本身提供的包中类的使用,一些程序需要创建多个方法完成,不过基本还是面向过程编程和使用c时还是差不了多少,题量一般
第三次作业
就我看来第三次作业才真正的进入面向对象编程,也就是要将原本的面向过程的思维方式转变过来,这次作业每个都需要创建多个自定类来完成目标,也正是通过这次作业才真正开始了解类和对象这个java最重要的概念,懂得了类中属性和方法的性质,开始以面向对象的思想来解决问题,题量较少,但花费的时间较之前要多很多
设计与分析
题目集一 7-8 判断三角形类型
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
double a[] = new double[3];
int i;
for(i = 0; i < 3; i++){
a[i] = in.nextDouble();
}
for(i = 0; i < 3; i++){
if(a[i] < 1 || a[i] > 200){
System.out.println("Wrong Format");
return;
}
}
Arrays.sort(a);
if(a[0] + a[1] > a[2]){
if(a[0] == a[1] && a[1] == a[2]){
System.out.println("Equilateral triangle");
}
else if(a[0] == a[1] && a[0] * a[0] + a[1] * a[1] - a[2] * a[2] < 0.000001)
System.out.println("Isosceles right-angled triangle");
else if(a[2] == a[1] || a[2] == a[0] || a[0] == a[1])
System.out.println("Isosceles triangle");
else if(a[0] * a[0] + a[1] * a[1] - a[2] * a[2] < 0.0000010)
System.out.println("Right-angled triangle");
else{
System.out.println("General triangle");
}
}
else
System.out.println("Not a triangle");
}
}
类图

代码source monitor分析
Metrics Details For File 'Main.java'
Parameter Value
========= =====
Project Directory C:\Users\14768\workspace\Contacts\src\com\atguigu\java/
File Name Main.java
Lines 41
Statements 27
Percent Branch Statements 33.3
Method Call Statements 8
Percent Lines with Comments 0.0
Classes and Interfaces 1
Methods per Class 1.00
Average Statements per Method 22.00
Line Number of Most Complex Method 8
Name of Most Complex Method Main.main()
Maximum Complexity 15
Line Number of Deepest Block 17
Maximum Block Depth 4
Average Block Depth 2.30
Average Complexity 15.00
Most Complex Methods in 1 Class(es): Complexity, Statements, Max Depth, Calls
Main.main() 15, 22, 4, 8
Block Depth Statements
0 4
1 1
2 9
3 9
4 4
5 0
6 0
7 0
8 0
9+ 0
代码设计分析
首先建立一个数组储存输入的三角形三条边,再利用sort方法对三条边进行排序,再用简单的if-else语句对各个条件分别判断是什么三角形
题目小结
在这道题中是我第一次使用java.util包中的除Scanner的其他类,通过查阅资料后知道了有Arrays这个非常方便的数组工具,对于数组的数字只需要简单的调用一个sort方法就可以轻松排序,而不需要写一个繁琐的排序函数.
题目集二 7-4 输入年月日的值(均为整型数),输出该日期的下一天
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner input=new Scanner(System.in);
int year,month,day;
year=input.nextInt();
month=input.nextInt();
day=input.nextInt();
if(!checkInputValidity(year,month,day)){
System.out.print("Wrong Format");
input.close();
return;
}
nextDate(year,month,day);
input.close();
}
public static boolean isLeapYear(int year){
if(year % 4 == 0 && year % 100 != 0 ||year % 400 == 0){
return true;
}else{
return false;
}
}
public static void nextDate(int year,int month,int day){
int []daysofMonth = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isLeapYear(year))
daysofMonth[2]=29;
if(day+1<=daysofMonth[month]){
System.out.printf("Next date is:"+year+"-"+month+"-"+(day+1));
}
else if(month+1<=12){
System.out.printf("Next date is:"+year+"-"+(month+1)+"-"+1);
}
else{
System.out.printf("Next date is:"+(year+1)+"-"+1+"-"+1);
}
}
public static boolean checkInputValidity(int year,int month,int day){
if(year<1820||year>2020){
return false;
}
else if(month<1||month>12){
return false;
}
else if(day<1||day>31){
return false;
}
int []daysofMonth = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isLeapYear(year)) 
daysofMonth[2]=29;
if(day>daysofMonth[month]){
return false;
}
return true;
}
}
类图

代码source monitor分析
Metrics Details For File 'Main.java'
Parameter Value
========= =====
Project Directory C:\Users\14768\workspace\Contacts\src\com\atguigu\java/
File Name Main.java
Lines 64
Statements 43
Percent Branch Statements 27.9
Method Call Statements 10
Percent Lines with Comments 0.0
Classes and Interfaces 1
Methods per Class 4.00
Average Statements per Method 9.00
Line Number of Most Complex Method 44
Name of Most Complex Method Main.checkInputValidity()
Maximum Complexity 6
Line Number of Deepest Block 16
Maximum Block Depth 3
Average Block Depth 2.05
Average Complexity 4.50
Most Complex Methods in 1 Class(es): Complexity, Statements, Max Depth, Calls
Main.checkInputValidity() 6, 12, 3, 1
Main.isLeapYear() 5, 4, 3, 0
Main.main() 2, 11, 3, 5
Main.nextDate() 5, 9, 3, 4
Block Depth Statements
0 3
1 4
2 24
3 12
4 0
5 0
6 0
7 0
8 0
9+ 0
代码设计分析
首先写一个check方法检测输入的年月日合法性,不合法则重新输入,在这道题中某一天的下一日不是简单加一的关系,一年是否为闰年,本日是否为最后一天都是这道题需要注意的,所以需要创建一个方法以判断是否为闰年,再建立一个数组储存一年中十二个月的日期数,碰到闰年的话二月的日期数要改为29,之后就可以利用写好的这些来计算下一日的日期,通过if-else判断本日是否为一个月的最后一天,以及是否为一年的最后一天,最后输出结果
题目小结
再写这道题时和写c时的感觉差不多,都是创建各个函数以完成相应功能,除了函数在这里叫方法,而这些方法要写在一个类里面以外,总体来说就是在写c
题目集二 7-5 输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0)时
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner input=new Scanner(System.in);
int year,month,day,n;
year=input.nextInt();
month=input.nextInt();
day=input.nextInt();
n=input.nextInt();
if(!checkInputValidity(year,month,day,n)){
System.out.print("Wrong Format");
input.close();
return;
}
agoDate(year,month,day,n);
input.close();
}
public static boolean isLeapYear(int year){
if(year % 4 == 0 && year % 100 != 0 ||year % 400 == 0){
return true;
}else{
return false;
}
}
public static void agoDate(int year,int month,int day,int m){
int n=-m;
int []daysofMonth = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isLeapYear(year))
daysofMonth[2]=29;
if(m<0){
if(day+n<=daysofMonth[month]){
System.out.printf(m+" days ago is:"+year+"-"+month+"-"+(day+n));
}
else if(month+1<=12){
System.out.printf(m+" days ago is:"+year+"-"+(month+1)+"-"+(day+n-daysofMonth[month]));
}
else{
System.out.printf(m+" days ago is:"+(year+1)+"-"+1+"-"+(day+n-daysofMonth[month]));
}
}
else{
if(day-m>0){
System.out.printf(m+" days ago is:"+year+"-"+month+"-"+(day-m));
}
else if(month-1>0){
System.out.printf(m+" days ago is:"+year+"-"+(month-1)+"-"+(daysofMonth[month-1]+day-m));
}
else{
System.out.printf(m+" days ago is:"+(year-1)+"-"+12+"-"+(daysofMonth[12]+day-m));
}
}
}
public static boolean checkInputValidity(int year,int month,int day,int n){
if(n<-10||n>10)
return false;
if(year<1820||year>2020){
return false;
}
else if(month<1||month>12){
return false;
}
else if(day<1||day>31){
return false;
}
int []daysofMonth = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isLeapYear(year))
daysofMonth[2]=29;
if(day>daysofMonth[month]){
return false;
}
return true;
}
}
类图

代码source monitor分析
Metrics Details For File 'Main.java'
Parameter Value
========= =====
Project Directory C:\Users\14768\workspace\Contacts\src\com\atguigu\java/
File Name Main.java
Lines 80
Statements 55
Percent Branch Statements 32.7
Method Call Statements 13
Percent Lines with Comments 0.0
Classes and Interfaces 1
Methods per Class 4.00
Average Statements per Method 12.00
Line Number of Most Complex Method 30
Name of Most Complex Method Main.agoDate()
Maximum Complexity 10
Line Number of Deepest Block 37
Maximum Block Depth 4
Average Block Depth 2.31
Average Complexity 6.00
Most Complex Methods in 1 Class(es): Complexity, Statements, Max Depth, Calls
Main.agoDate() 10, 18, 4, 7
Main.checkInputValidity() 7, 14, 3, 1
Main.isLeapYear() 5, 4, 3, 0
Main.main() 2, 12, 3, 5
Block Depth Statements
0 3
1 4
2 27
3 15
4 6
5 0
6 0
7 0
8 0
9+ 0
代码设计分析
这一题做法与上一题大抵相似,除了在计算天数时需要根据输入的天数来进行加减以外,设计思路相同
题目小结
在上一题的基础上稍加修改
题目集三 7-2 定义一个类Date,包含三个私有属性年(year)、月(month)、日(day)
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner input=new Scanner(System.in);
int year=input.nextInt();
int month=input.nextInt();
int day=input.nextInt();
Date date=new Date(year,month,day);
if(!date.cheakInputVility()){
System.out.print("Date Format is Wrong");
input.close();
return;
}
date.getNextDate();
input.close();
}
}
class Date{
private int year,month,day;
int[] mon_maxnum = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
Date(){
}
Date(int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
}
int getYear(){
return year;
}
void setYear(int year){
this.year=year;
}
int getMonth(){
return month;
}
void setMonth(int month){
this.month=month;
}
int getDay(){
return day;
}
void setDay(int day){
this.day=day;
}
boolean isLeapYear(int year){
if(year % 4 == 0 && year % 100 != 0 ||year % 400 == 0){
return true;
}else{
return false;
}
}
boolean cheakInputVility(){
if(year<1900||year>2000){
return false;
}
else if(month<1||month>12){
return false;
}
else if(day<1||day>31){
return false;
}
if(isLeapYear(year))
mon_maxnum[2]=29;
else
mon_maxnum[2]=28;
if(day>mon_maxnum[month]){
return false;
}
return true;
}
void getNextDate(){
if(isLeapYear(year))
mon_maxnum[2]=29;
else
mon_maxnum[2]=28;
if(day+1<=mon_maxnum[month]){
System.out.printf("Next day is:"+year+"-"+month+"-"+(day+1));
}
else if(month+1<=12){
System.out.printf("Next day is:"+year+"-"+(month+1)+"-"+1);
}
else{
System.out.printf("Next day is:"+(year+1)+"-"+1+"-"+1);
}
}
}
类图

代码source monitor分析
Metrics Details For File 'Main.java'
Parameter Value
========= =====
Project Directory C:\Users\14768\workspace\Contacts\src\com\atguigu\java/
File Name Main.java
Lines 99
Statements 65
Percent Branch Statements 21.5
Method Call Statements 10
Percent Lines with Comments 0.0
Classes and Interfaces 2
Methods per Class 6.00
Average Statements per Method 3.92
Line Number of Most Complex Method 63
Name of Most Complex Method Date.cheakInputVility()
Maximum Complexity 7
Line Number of Deepest Block 15
Maximum Block Depth 3
Average Block Depth 1.85
Average Complexity 2.33
Most Complex Methods in 2 Class(es): Complexity, Statements, Max Depth, Calls
Date.cheakInputVility() 7, 13, 3, 1
Date.Date() 1, 3, 2, 0
Date.Date() 1, 0, 0, 0
Date.getDay() 1, 1, 2, 0
Date.getMonth() 1, 1, 2, 0
Date.getNextDate() 6, 10, 3, 4
Date.getYear() 1, 1, 2, 0
Date.isLeapYear() 5, 4, 3, 0
Date.setDay() 1, 1, 2, 0
Date.setMonth() 1, 1, 2, 0
Date.setYear() 1, 1, 2, 0
Main.main() 2, 11, 3, 5
Block Depth Statements
0 4
1 14
2 35
3 12
4 0
5 0
6 0
7 0
8 0
9+ 0
代码设计分析
本体只要求定义一个类,所以在算法上不需要多做要求,只要按照题目所给的类图一步步创建好一个类就行,其中的方法也可以照搬前面的方法
题目小结
通过这道题真正的自己创建了一个类,而后在Main中创建了该类的对象,使用对象来完成工作,对类与对象的理解更深了
题目集三 7-3 编写程序性,实现对简单多项式的导函数进行求解
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String initExpress = input.nextLine();
String express = initExpress.replaceAll("\\s", "");
Express textExpress = new Express(express);
if (textExpress.check())
textExpress.show();
else
System.out.println("Wrong Format");
}
}
class Express {
private String express;
private String term;
private String ratStr;// 系数部分
private String indexStr;// 指数部分
private BigInteger rat;
private BigInteger index;
private ArrayList<String> containTerm = new ArrayList<>();
public Express(String express) {
this.express = express;
}
String termExpress = "([+-]?[1-9][0-9]*)?" + "(\\*?[+-]?x(\\^([+-]?[1-9][0-9]*))?)?";
String wholeExpress = "(([+-]?[1-9][0-9]*)?" + "(\\*?[+-]?x(\\^([+-]?[1-9][0-9]*))?)?)+";
String constNum = "[+-]?[0-9]+";
public boolean check() {
return Pattern.matches(wholeExpress, express);
}
public void show() {
if (Pattern.matches(constNum, express)) {
System.out.println("0");
System.exit(0);
}
Pattern p = Pattern.compile(termExpress);
Matcher m = p.matcher(express);
int flag = 0;
while (m.find()) {
ratStr = m.group(1);
indexStr = m.group(4);
if (ratStr != null) {
rat = new BigInteger(ratStr);
if (m.group(2) != null && m.group(2).startsWith("-")) {
rat = BigInteger.valueOf(-1);
}
else if (m.group(2) != null && m.group(2).startsWith("+")) {
rat = BigInteger.valueOf(1);
}
} else {
rat = BigInteger.valueOf(1);
if (m.group() != null && m.group().startsWith("-")) {
rat = BigInteger.valueOf(-1);
}
else if (m.group() != null && m.group().startsWith("+")) {
rat = BigInteger.valueOf(1);
}
}
if (indexStr != null) {
index = new BigInteger(indexStr);
rat = rat.multiply(index);
index = index.subtract(new BigInteger("1"));
if (rat.compareTo(new BigInteger("0")) > 0 && flag == 1)
System.out.print("+" + (rat.equals(new BigInteger("-1")) ? "-x" : rat + "*x") + (index.equals(new BigInteger("1")) ? "" : ("^" + index)));
else {
flag = 1;
System.out.print((rat.equals(new BigInteger("-1")) ? "-x" : rat + "*x") + (index.equals(new BigInteger("1")) ? "" : ("^" + index)));
}
} else if (m.group(2) != null) {
if(flag == 1 && rat.compareTo(new BigInteger("0")) > 0)
System.out.print("+"+rat)
else{
flag = 1;
System.out.print(rat);
}
}
}
}
}
类图

代码source monitor分析
Metrics Details For File 'Main.java'
Parameter Value
========= =====
Project Directory C:\Users\14768\workspace\Contacts\src\com\atguigu\java/
File Name Main.java
Lines 93
Statements 67
Percent Branch Statements 22.4
Method Call Statements 45
Percent Lines with Comments 10.8
Classes and Interfaces 2
Methods per Class 2.00
Average Statements per Method 11.25
Line Number of Most Complex Method 37
Name of Most Complex Method Express.show()
Maximum Complexity 21
Line Number of Deepest Block 52
Maximum Block Depth 5
Average Block Depth 2.45
Average Complexity 6.50
Most Complex Methods in 2 Class(es): Complexity, Statements, Max Depth, Calls
Express.check() 1, 1, 2, 1
Express.Express() 1, 1, 2, 0
Express.show() 21, 35, 5, 38
Main.main() 3, 8, 2, 5
Block Depth Statements
0 8
1 14
2 15
3 8
4 14
5 8
6 0
7 0
8 0
9+ 0
代码设计分析
express变量存储输入的表达式
分别存储表达式中的系数和指数
分别储存表达式单项,表达式,常量表达式的正则表达式
算法设计方面,首先判断变量express与wholeexpress的正则表达式是否匹配,即判断输入表达式是否合法,确定合法后再检验表达式是否为常量表达式,若是,则输出0并停止程序,之后再对表达式中的每一个单项的系数和指数分别为0的情况进行判断,按照题目要求分别输出正确的导函数
题目小结
这道题的难度相较之前的提升了很多,正则表达式在之前是从未接触过的内容,所以必须自学,在理解了正则表达式的运作原理和作用后,可以将表达式的每一个项单独拆分出来,并且可以利用Matcher类中的group方法将单个项的各个元素继续分组拆分以单独分析,在将复杂表达式不断拆分后,题目就变得十分简单了起来,之后只需要对各个项中可能引起不同结果的各个元素例如系数做if-else判断就行,通过这道题我发现了许多方便使用的api,也明白了要真正的写好一个java程序是离不开正确使用这些api的。
踩坑心得
- 在题目集一 7-1中,因为是写的第一个程序,对于一些新事物还明显不熟练,在创建Scanner对象时忘了写System.in导致报错
![]()
Scanner input = new Scanner();
- 在题目集三 7-1中,将Account类的成员变量id设为了private,在写id的赋值方法idsetter时直接写的赋值操作,但结果没有成功赋值
在id前面添加了this后成功为变量赋值
3.在题目集三 7-3中,将代码提交上去后无法通过大数测试点,发现是设定的系数和指数的Integer类型精度不足,查阅资料后将其改成BigInteger,但在使用该类对象时将其与int类型的数字比对时用了=号导致报错
System.out.print("+" + (rat==-1) ? "-x" : rat + "*x") + (index==1) ? "" : ("^" + index)));
改进建议
1.对于题目集三 7-2的check方法,其中用了大量的if-else来完成判断,但其中很多都是重复的工作,完全可以将判断条件写在一个if里面,可以大大减低阅读难度
2.对于题目集三 7-3一开始的输出使用的是多个if判断来实现不同结果的输出
if(rat.equals(new BigInteger("-1"))){
if(index.equals(new BigInteger("1")))
System.out.print("+"+"-x"+"");
else
System.out.println("+"+"-x"+"^"+index);
}
这样写不仅复杂而且繁琐,浪费时间和精力,将其修改为下面的代码后简单易读
System.out.print("+" + (rat.equals(new BigInteger("-1")) ? "-x" : rat + "*x") + (index.equals(new BigInteger("1")) ? "" : ("^" + index)));
总结
上述三个题目集中,我学到了很多东西,最重要的一点就是加强了我的编码能力,以前基本遇到编程的题目
即使是一个简单的编程题目,我都需要想好久时间才能能动手去做,并且做完需要花费好多时间,虽然这次三个题目
也花费了我获得时间,但做完后我感觉编程原来也没有我想象的那么难,只要把思路整理好,构建好基本得流程
写代码也就一会的事
还有就是本阶段的三个题目集做完后,让我懂得了无论是编写代码还是做别的什么事情,都要细心不浮躁,就比如求日期的
题目中,一旦粗心大意,就很容易漏东西,导致拿不到分数
我觉得我需要进一步学习得地方有很多,有编写代码得速度需要提高,数学公式需要加强掌握。

在id前面添加了this后成功为变量赋值
浙公网安备 33010602011771号