一、前言

第一次作业:

1、题目较多,总共有8题

2、难度较小,主要是一些比较初级的语法

3、所包括的知识点有类的创建,键盘数据输入,定义数组等

第二次作业:

1、题目数量稍稍有点多,总共有5题

2、难度也不算很大,就是计算下一天、前n天有点把人绕晕

3、需要在类里面定义多个函数,返回boolean值

第三次作业:

1、题目数量合适,总共3题

2、难度对我来讲很大

3、知识点包括无参构造方法,getter及setter方法以及正则表达式

 

二、设计与分析

第一次作业:

这次作业因为是第一次写java,所以整体来说题目都不算太难,值得一说的是7-4 计算税率和7-8 判断三角形类型这两题

7-4计算税率:

美国联邦个人所得税是根据申报情况和应纳税所得额计算的。有四种申报情况:单身申报、已婚联合申报、已婚单独申报、户主申报。税率每年都不一样。下表即为假定税率计算方法,例如,某人单身申报,应纳税收入为10,000,则计算方法为:8,350的部分按10%计税,剩余的1,650的部分按158,350×10%+1,650×151,082.5。

你要写一个计算个人所得税的程序。程序应该首先输入申报状态和应纳税所得额并计算税款。其中,输入申报状态用整型数表示,0表示单身申报,1表示已婚联合申报,2表示已婚单独申报,3表示户主申报。应纳税所得金额用实型数表示。下表为具体的税率。

 PTA1~3的作业总结Blog_整型

  1 import java.util.Scanner;
  2 public class Main
  3 {
  4     public static void main(String[] args)
  5     {
  6         Scanner input = new Scanner(System.in);
  7         int a,b,c,d,e;
  8         double tax = 0;
  9         int type = input.nextInt();
 10         int money = input.nextInt();
 11         if(money>=0)
 12         {
 13             switch(type)
 14             {
 15                 case 0:
 16                     a=8350;
 17                     b=33950;
 18                     c=82250;
 19                     d=171550;
 20                     e=372950;
 21                     if(money<=a)
 22                     {
 23                         tax = money * 0.1;
 24                     }
 25                     if(money>a&&money<=b)
 26                     {
 27                         tax = a * 0.1 + (money - a)*0.15;
 28                     }
 29                     if(money>b&&money<=c)
 30                     {
 31                         tax = a * 0.1 + (b-a)*0.15+(money - b)*0.25;
 32                     }
 33                     if(money>c&&money<=d)
 34                     {
 35                         tax = a * 0.1 + (b-a)*0.15+(c - b)*0.25+(money-c)*0.28;
 36                     }
 37                     if(money>d&&money<=e)
 38                     {
 39                         tax = a * 0.1 + (b-a)*0.15+(c - b)*0.25+(d-c)*0.28+(money-d)*0.33;
 40                     }
 41                     if(money>e)
 42                     {
 43                         tax = a * 0.1 + (b-a)*0.15+(c - b)*0.25+(d-c)*0.28+(e-d)*0.33+(money-e)*0.35;
 44                     }
 45                     System.out.println(tax);
 46                     break;
 47                 case 1:
 48                     a=16700;
 49                     b=67900;
 50                     c=137050;
 51                     d=208850;
 52                     e=372950;
 53                     if(money<=a)
 54                     {
 55                         tax = money * 0.1;
 56                     }
 57                     if(money>a&&money<=b)
 58                     {
 59                         tax = a * 0.1 + (money - a)*0.15;
 60                     }
 61                     if(money>b&&money<=c)
 62                     {
 63                         tax = a * 0.1 + (b-a)*0.15+(money - b)*0.25;
 64                     }
 65                     if(money>c&&money<=d)
 66                     {
 67                         tax = a * 0.1 + (b-a)*0.15+(c - b)*0.25+(money-c)*0.28;
 68                     }
 69                     if(money>d&&money<=e)
 70                     {
 71                         tax = a * 0.1 + (b-a)*0.15+(c - b)*0.25+(d-c)*0.28+(money-d)*0.33;
 72                     }
 73                     if(money>e)
 74                     {
 75                         tax = a * 0.1 + (b-a)*0.15+(c - b)*0.25+(d-c)*0.28+(e-d)*0.33+(money-e)*0.35;
 76                     }
 77                     System.out.println(tax);
 78                     break;
 79                 case 2:
 80                     a=8350;
 81                     b=33950;
 82                     c=68525;
 83                     d=104425;
 84                     e=186475;
 85                     if(money<=a)
 86                     {
 87                         tax = money * 0.1;
 88                     }
 89                     if(money>a&&money<=b)
 90                     {
 91                         tax = a * 0.1 + (money - a)*0.15;
 92                     }
 93                     if(money>b&&money<=c)
 94                     {
 95                         tax = a * 0.1 + (b-a)*0.15+(money - b)*0.25;
 96                     }
 97                     if(money>c&&money<=d)
 98                     {
 99                         tax = a * 0.1 + (b-a)*0.15+(c - b)*0.25+(money-c)*0.28;
100                     }
101                     if(money>d&&money<=e)
102                     {
103                         tax = a * 0.1 + (b-a)*0.15+(c - b)*0.25+(d-c)*0.28+(money-d)*0.33;
104                     }
105                     if(money>e)
106                     {
107                         tax = a * 0.1 + (b-a)*0.15+(c - b)*0.25+(d-c)*0.28+(e-d)*0.33+(money-e)*0.35;
108                     }
109                     System.out.println(tax);
110                     break;
111                 case 3:
112                     a=11950;
113                     b=45500;
114                     c=117450;
115                     d=190200;
116                     e=372950;
117                     if(money<=a)
118                     {
119                         tax = money * 0.1;
120                     }
121                     if(money>a&&money<=b)
122                     {
123                         tax = a * 0.1 + (money - a)*0.15;
124                     }
125                     if(money>b&&money<=c)
126                     {
127                         tax = a * 0.1 + (b-a)*0.15+(money - b)*0.25;
128                     }
129                     if(money>c&&money<=d)
130                     {
131                         tax = a * 0.1 + (b-a)*0.15+(c - b)*0.25+(money-c)*0.28;
132                     }
133                     if(money>d&&money<=e)
134                     {
135                         tax = a * 0.1 + (b-a)*0.15+(c - b)*0.25+(d-c)*0.28+(money-d)*0.33;
136                     }
137                     if(money>e)
138                     {
139                         tax = a * 0.1 + (b-a)*0.15+(c - b)*0.25+(d-c)*0.28+(e-d)*0.33+(money-e)*0.35;
140                     }
141                     System.out.println(tax);
142                     break;
143                 default:
144                     System.out.println("Wrong Format");
145 
146             }
147         }
148         else
149         {
150             System.out.println("Wrong Format");
151         }
152     }
153 
154 }

 

 这一题最有特点的就是它里面的数据非常多,包含了好几个等级,写代码的时候后也不得不手打上去那些等级数据,非常耗时间。我用的是switch语句,将每一级的税率和计算方法打上去,非常复杂,而且有好多重复语句,类似下面几种情况的语句重复出现了好几次。其实可以写一个函数来专门计算税率的,但由于当时刚开始写java,没有想这么多,所以用了这种最常见的C语言写法。

 

7-8判断三角形类型 :

输入三角形三条边,判断该三角形为什么类型的三角形。

输入格式:

在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]。

输出格式:

(1)如果输入数据非法,则输出“Wrong Format”; (2)如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”; (3)如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”; (3)如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”; (5)如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”; (6)如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”; (7)如果输入数据合法且能够成一般三角形,则输出“General triangle”。

 1 import java.util.Scanner;
 2 public class Main
 3 {
 4     public static void main(String[] args)
 5     {
 6         Scanner input = new Scanner(System.in);
 7         double a = input.nextDouble();
 8         double b = input.nextDouble();
 9         double c = input.nextDouble();
10         double tmp;
11         if(a>b)
12         {
13             tmp=a;a=b;b=tmp;
14         }
15         if(a>c)
16         {
17             tmp=a;a=c;c=tmp;
18         }
19         if(b>c)
20         {
21             tmp=b;b=c;c=tmp;
22         }
23         if(a>=1&&a<=200&&b>=1&&b<=200&&c>=1&&c<=200)
24         {
25             if(a+b>c)
26             {
27                 if(a==b&&b==c)
28                 {
29                     System.out.println("Equilateral triangle");
30                 }
31                 else if(a==b&&a*a+b*b-c*c<0.000001)
32                 {
33                     System.out.println("Isosceles right-angled triangle");
34                 }
35                 else if((a==b&&b!=c)||(b==c&&c!=a))
36                 {
37                     System.out.println("Isosceles triangle");
38                 }
39                 else if(a!=b&&a*a+b*b-c*c<0.000001)
40                 {
41                     System.out.println("Right-angled triangle");
42                 }
43                 else
44                 {
45                     System.out.println("General triangle");
46                 }
47             }
48             else
49             {
50                 System.out.println("Not a triangle");
51             }
52         }
53         else
54         {
55             System.out.println("Wrong Format");
56         }
57     }
58 
59 }

 

这题的内容是输入三角形三条边,判断该三角形为什么类型的三角形,要求判断的有等边、等腰、等腰直角、直角和一般三角形。我先判断出三遍的大小,选出最长的那条边,然后根据三遍是否相等来判断等边三角形,判断完等边三角形之后接着判断等腰直角和等腰三角形,最后判断是否是直角三角形。

 

PTA1~3的作业总结Blog_子函数_02

从图中可以看出圈复杂度非常大,可读性很差,代码完成度很低

里面用了许多的if、else嵌套来筛选三角形三边的关系,造成分支数目多

 

第二次作业

7-4求下一天:

本题要求输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31]

 1 import java.util.Scanner;
 2 public class Main
 3 {
 4     public static boolean isLeapYear(int year) //判断year是否为闰年,返回boolean类型
 5     {
 6         boolean isLeapYear;
 7         isLeapYear=((year%4==0&&year%100!=0)||year%400==0);
 8         return isLeapYear;
 9     }
10     public static boolean checkInputValidity(int year,int month,int day)//判断输入日期是否合法,返回布尔值
11     {
12         boolean checkInputValidity;
13         int[] a=new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
14         if(isLeapYear(year))
15         {
16             a[1]=29;
17         }
18         checkInputValidity=year>=1820&&year<=2020&&month>=1&&month<=12&&day<=a[month-1]&&day>0;
19             return checkInputValidity;
20     }
21     public static void nextDate(int year,int month,int day)  //求输入日期的下一天
22     {
23         int[] a=new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
24         if(isLeapYear(year))
25         {
26             a[1] = 29;
27         }
28         int i=0,j=0,k=0;
29         if(month==12)
30         {
31             if(day==a[month-1])
32             {
33                 i=year+1;
34                 j=1;k=1;
35             }
36             else
37             {
38                 i=year;
39                 j=month;
40                 k=day+1;
41             }
42         }
43         if(month<12)
44         {
45             if(day==a[month-1])
46             {
47                i=year; j=month+1;
48                 k=1;
49             }
50             else
51             {
52                 i=year;
53                 j=month;
54                 k=day+1;
55             }
56         }
57         System.out.println("Next date is:"+i+"-"+j+"-"+k);
58     }
59     public static void main(String[] args)//主方法
60     {
61         Scanner input = new Scanner(System.in);
62         int year = input.nextInt();
63         int month = input.nextInt();
64         int day = input.nextInt();
65         if(checkInputValidity(year,month,day))
66         {
67             nextDate(year,month,day);
68         }
69         else
70         {
71             System.out.println("Wrong Format");
72         }
73     }
74 }

 

 

首先在类中建立各个函数,建立函数的目的是使得主函数看起来清晰简洁,便于阅读

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) ; //求输入日期的下一天

 

接下来重点分析nextDate函数

要计算出下一天先要判断这一年是否为闰年,判断完平闰年后再判断该月是否为最后一个月12月,如果是十二月的最后一天,那年份就要再加一年,变成来年的一月一日

使用了函数结构,以及分支不多,所以源代码的圈复杂度很低,具有较好的可读性

而且子函数中也只有少数的判断语句,没有使用过多的循环,代码读起来也比较简单易懂

PTA1~3的作业总结Blog_取值范围_03

 

 7-5求前N天:

输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。
注意:不允许使用Java中任何与日期有关的类或方法。

  1 import java.util.Scanner;
  2 public class Main
  3 {
  4     public static boolean isLeapYear(int year) //判断year是否为闰年,返回boolean类型
  5     {
  6         boolean isLeapYear;
  7         isLeapYear=((year%4==0&&year%100!=0)||year%400==0);
  8         return isLeapYear;
  9     }
 10     public static boolean checkInputValidity(int year,int month,int day,int n)//判断输入日期是否合法,返回布尔值
 11     {
 12         boolean checkInputValidity;
 13         int[] a=new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 14         if(isLeapYear(year))
 15         {
 16             a[1]=29;
 17         }
 18         checkInputValidity=year>=1820&&year<=2020&&month>=1&&month<=12&&day<=a[month-1]&&day>0&&n>=-10&&n<=10;
 19             return checkInputValidity;
 20     }
 21     public static void daysAgo(int year,int month,int day,int n)
 22     {
 23         int[] a=new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
 24         if(isLeapYear(year))
 25         {
 26             a[1] = 29;
 27         }
 28         int i=0,j=0,k=0;
 29         if(month==12)
 30         {
 31             if(day-n>a[month-1])//n days later
 32             {
 33                 i=year+1;
 34                 j=1;
 35                 k=day-n-a[11];
 36             }
 37             else if(day-n<0)//n days ago
 38             {
 39                 i=year;
 40                 j=month-1;
 41                 k=a[month-2]+day-n;
 42             }
 43             else
 44             {
 45                 i=year;
 46                 j=month;k=day-n;
 47             }
 48         }
 49         else if(month==1)
 50         {
 51             if(day-n<0)//n days ago
 52             {
 53                 i=year-1;j=12;k=a[11]+day-n;
 54             }
 55             else if(day-n>a[month-1])//n days later
 56             {
 57                 i=year;
 58                 j=month+1;
 59                 k=day-n-a[month-1];
 60             }
 61             else
 62             {
 63                 i=year;j=month;k=day-n;
 64             }
 65         }
 66         else
 67         {
 68             if(day-n>a[month-1])//n days later
 69             {
 70                 i=year;j=month+1;k=day-n-a[month-1];
 71             }
 72             else if(day-n<0)
 73             {
 74                 i=year;
 75                 j=month-1;
 76                 k=day-n+a[month-2];
 77             }
 78             else
 79             {
 80                 i=year;j=month;k=day-n;
 81             }
 82         }
 83         System.out.println(n+" days ago is:"+i+"-"+j+"-"+k);
 84     }
 85     public static void main(String[] args)//主方法
 86     {
 87         Scanner input = new Scanner(System.in);
 88         int year = input.nextInt();
 89         int month = input.nextInt();
 90         int day = input.nextInt();
 91         int n = input.nextInt();
 92         if(checkInputValidity(year,month,day,n))
 93         {
 94             daysAgo(year,month,day,n);
 95         }
 96         else
 97         {
 98             System.out.println("Wrong Format");
 99         }
100     }
101 }

 

 

这一题和7-4很相似,也是采用建立子函数的方法完成的,子函数如下

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 daysAgo(int year,int month,int day,int n);//判断前N天

 

主要函数daysAgo()

要判断前n天,不仅要判断是否跨年,还要判断是否跨月。首先还是先判断平闰年,然后再判断是否是1月,如果是的话,还要再判断前n天是否是去年,如果是的话就要将年份减一,接着判断其他月份,其他月份再根据前n天来进行月份的减一

由于建立了多个子函数,且没有过多的分支,源代码的圈复杂度很低,可读性很好

PTA1~3的作业总结Blog_数据_04

 

第三次作业

7-2

定义日期类:

定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。

要求:Date类结构如下图所示:

PTA1~3的作业总结Blog_取值范围_05

 

这题相当于要使用无参构造方法以及getter和setter方法,然后在主类里面建立一个Date类

Date类里面包含了判断闰年、判断输入日期是否合法、求下一天的子函数。

判断闰年以及求下一天函数和前面那题一样

主函数中直接输入日期,通过调用Date类来执行计算操作


  1 import java.util.Scanner;
  2 public class Main {
  3 public static void main(String args[]){
  4 Scanner input=new Scanner(System.in);
  5 int year=input.nextInt();
  6 int month=input.nextInt();
  7 int day=input.nextInt();
  8 Date date=new Date(year,month,day);
  9 if(!date.checkInputValidity(year,month,day)){
 10 System.out.println ("Date Format is Wrong");
 11 }
 12 else{
 13 date.getNextDate(year,month,day);
 14 }
 15 }
 16 }
 17 class Date {
 18 private int year=0;
 19 private int month=0;
 20 private int day=0;
 21 int[] mon_maxnum = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 22 
 23 public Date() {
 24 
 25 }
 26 
 27 public Date(int year, int month, int day) {
 28 this.day = day;
 29 this.month = month;
 30 this.year = year;
 31 }
 32 
 33 public int getDay() {
 34 return day;
 35 }
 36 
 37 public void setDay(int day) {
 38 this.day = day;
 39 }
 40 
 41 public int getMonth() {
 42 return month;
 43 }
 44 
 45 public void setMonth(int month) {
 46 this.month = month;
 47 }
 48 
 49 public int getYear() {
 50 return year;
 51 }
 52 
 53 public void setYear(int year) {
 54 this.year = year;
 55 }
 56 
 57 public boolean isLeapYear(int year) {
 58 if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
 59 return true;
 60 else
 61 return false;
 62 }
 63 
 64 public boolean checkInputValidity(int year, int month, int day)//判断输入日期是否合法,返回布尔值
 65 {
 66 if(isLeapYear(year))
 67 {
 68 mon_maxnum[2]=29;
 69 }
 70 if((year>=1900&&year<=2000)&&(month>=1&&month<=12)&&(day<=mon_maxnum[month]&&day>0))
 71 {
 72 return true;
 73 }
 74 else
 75 return false;
 76 }
 77 
 78 public void getNextDate(int year, int month, int day) //求输入日期的下一天
 79 {
 80 if (isLeapYear(year)) {
 81 mon_maxnum[2] = 29;
 82 }
 83 int i = 0, j = 0, k = 0;
 84 if (month == 12) {
 85 if (day == mon_maxnum[month]) {
 86 i = year + 1;
 87 j = 1;
 88 k = 1;
 89 } else {
 90 i = year;
 91 j = month;
 92 k = day + 1;
 93 }
 94 }
 95 if (month < 12) {
 96 if (day == mon_maxnum[month]) {
 97 i = year;
 98 j = month + 1;
 99 k = 1;
100 } else {
101 i = year;
102 j = month;
103 k = day + 1;
104 }
105 }
106 System.out.println("Next day is:"+i+"-"+j+"-"+k);
107 }
108 }

 

 

 

7-3

一元多项式求导(类设计):

编写程序性,实现对简单多项式的导函数进行求解。详见作业指导书。 

该题对我来说难度太大,不在我的能力范围内,所以没有写,就不做分析了 

 

三、踩坑心得

 第一次作业

1.刚开始不知道怎么从键盘输入数据,以为和C语言一样,结果要调用Scanner类

2.定义一维数组要用int[]的形式

3.if和else if功能不一样,要注意区分

 第二次作业

1.四则运算用Math类

2.boolean是一个数据类型,它只有true和false两个值

3.下一天包括跨年,要格外注意12月份和其他月份不一样

4.还有前n天,注意是前n天,不是后n天,我第一次写成后n天了,结果一提交答案全错

 第三次作业

1.private修饰属性,只能在本类中使用,其他类无法进行访问

2.定义构造函数能更方便的定义新类,setter和getter函数是固定的,不要轻易更改

3.正则还没学

 

四、改进建议 

第一次作业比较简单,里面没有复杂的多类情况,也没有出现构建子函数等要求,有C语言基础就可以写好,没有过多的改进。

第二次作业测了一下圈复杂度,可读性还是比较好的。最后一题求前n天,分了几种情况讨论,有跨年的,跨月的,还有前n天和本月是同一个月。在讨论跨年的时候,我把12月也讨论了一下,然后发现并没有必要,因为要求的是前n天,并不是后n天,所以即使在12月也不可能跨年,这种情况可以去掉。

第三次作业有难度,正则那题到现在还没写,等写完再说吧。

 

五、总结 

总结:

学的还是不够多,书看少了,发的那本教材都没怎么翻过,有问题都是上网查资料,其实书上的解释更加详细,对于刚开始学java的同学来说还是要把基础打好。通过这三次作业,对java有了比较初步的了解,有些语法和C语言很相似,但所有的函数方法等都必须要在类里面实现,不能超出类外面,包括输入数据,输出等都需要调用类的方法。定义类的话可以在类里面加入和类名相同的构造函数

一些小建议:

作业难度如果大的话题量能不能适当减少,不然一次作业题目又多难度又大要花好长时间才能完成