题目集4~6的总结性Blog

2023-03-15,,

题目集4~6的总结性Blog


(1)前言

在这三次作业中,主要考察了正则表达式以及类间的关系。在这三次作业中,相比之下,第四次以及第五次作业的难度明显高于第六次作业,题量与难度相较于以往的作业也有明显提升,前两次作业奋斗到截止时间也仍然没有得到满分(呜呜我是废物),这让我意识到自己在程序设计时考虑的不充分以及自己代码编写能力的不足,希望自己在后续的学习中能再接再厉吧


(2)设计与分析

  ①题目集4(7-2)、题目集5(7-4)两种日期类聚合设计的优劣比较

首先先放代码和类图吧

题目集4(7-2)

  1 import java.util.Scanner;
2
3 public class Main {
4 public static void main(String[] args) {
5 Scanner input = new Scanner(System.in);
6 int choice = input.nextInt();
7 int d,m,y;
8 int n;
9 switch (choice){
10 case 1: //测试输入日期的下n天
11 y = input.nextInt();
12 m = input.nextInt();
13 d = input.nextInt();
14 n = input.nextInt();
15 DateUtil date1 = new DateUtil(d,m,y);
16
17 if(date1.checkInputValidity()&& n>0) {
18 date1 = date1.getNextNDays(n);
19 System.out.println(date1.showDate());
20 }
21 else
22 System.out.print("Wrong Format");
23
24 break;
25 case 2://测试输入日期的前n天
26 y = input.nextInt();
27 m = input.nextInt();
28 d = input.nextInt();
29 n = input.nextInt();
30 DateUtil date2 = new DateUtil(d,m,y);
31
32 if(date2.checkInputValidity()&& n>0) {
33 date2 = date2.getPreviousDays(n);
34 System.out.println(date2.showDate());
35 }
36 else
37 System.out.print("Wrong Format");
38 break;
39
40 case 3://测试两个日期之间相差的天数
41 y = input.nextInt();
42 m = input.nextInt();
43 d = input.nextInt();
44 DateUtil date3 = new DateUtil(d,m,y);
45
46 y = input.nextInt();
47 m = input.nextInt();
48 d = input.nextInt();
49 DateUtil date4 = new DateUtil(d,m,y);
50
51 int c;
52 if(date3.checkInputValidity() && date4.checkInputValidity()){
53 c= date3.getDaysofDates(date4);
54 System.out.println(c);
55 }
56 else
57 System.out.print("Wrong Format");
58 break;
59
60 default:
61 System.out.print("Wrong Format");
62
63 }//选择功能主题
64 }
65 }
66
67
68 class DateUtil{
69 private Day day;
70
71 public DateUtil(){
72
73 }
74
75 public DateUtil(int d,int m,int y) {
76 this.day = new Day(y,m,d);
77 }
78
79 public boolean checkInputValidity(){
80 return this.getDay().validate() && this.getDay().getMonth().validate() && this.getDay().getMonth().getYear().validate();
81 }//校验数据合法性
82
83 public boolean compareDates(DateUtil date){
84 if(this.getDay().getMonth().getYear().getValue() >date.getDay().getMonth().getYear().getValue()) {
85 return true;
86 } else if(this.getDay().getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()&&this.getDay().getMonth().getValue() > date.getDay().getMonth().getValue()) {
87 return true;
88 } else return this.getDay().getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue() && this.getDay().getMonth().getValue() == date.getDay().getMonth().getValue() && this.getDay().getValue() > date.getDay().getValue();
89
90 }//比较两个日期的大小,大则返回true,小为false
91
92 public boolean equalTwoDates(DateUtil date){
93 return this.getDay().getValue() == date.getDay().getValue() && this.getDay().getMonth().getValue() == date.getDay().getMonth().getValue() && this.getDay().getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue();
94 }//两个日期是否相等
95
96 public String showDate(){
97 return this.getDay().getMonth().getYear().getValue()+"-"+this.getDay().getMonth().getValue()+"-"+this.getDay().getValue();
98 }//日期值格式化
99
100 public DateUtil getNextNDays(int n){//求下n天
101 for(int i =0; i<n;i++){
102 this.getDay().dayIncrement();
103 }
104 return this;
105 }
106
107 public DateUtil getPreviousDays(long n){//求前n天
108 for(int i =0; i<n;i++){
109 this.getDay().dayReduction();
110 }
111 return this;
112 }
113
114 public int getDaysofDates(DateUtil date){//求两个日期之间的天数
115 int count=0;
116 if(!this.compareDates(date)){
117 while(!this.equalTwoDates(date)){
118 this.getDay().dayIncrement();
119 count += 1;
120 }
121 }
122 else{
123 while(!this.equalTwoDates(date)){
124 this.getDay().dayReduction();
125 count += 1;
126 }
127 }
128
129 return count;
130 }
131
132 public Day getDay() {
133 return day;
134 }
135
136 }
137
138 class Day{
139 private int value;
140 private Month month;
141 int[] mon_minnum={0,31,28,31,30,31,30,31,31,30,31,30,31};//非闰年
142 int[] mon_maxnum={0,31,29,31,30,31,30,31,31,30,31,30,31};//闰年
143
144 public Day(){
145
146 }
147
148 public Day(int yearValue,int monthValue,int dayValue) {
149 setValue(dayValue);
150 this.month = new Month(yearValue,monthValue);
151 }
152
153 public void resetMin(){
154 this.value = 1;
155 this.getMonth().monthIncrement();
156 }//日期复位(1)
157
158 public void resetMax(){
159 this.getMonth().monthReduction();
160 if(this.getMonth().getYear().isLeapYear())
161 this.value = mon_maxnum[this.getMonth().getValue()];
162 else
163 this.value = mon_minnum[this.getMonth().getValue()];
164 }//日期复位最大值
165
166 public boolean validate(){
167 if(this.getMonth().validate()) {
168 if (this.getMonth().getYear().isLeapYear()) {
169 return this.value > 0 && getValue() <= mon_maxnum[this.getMonth().getValue()];
170 } else {
171 return this.value > 0 && getValue() <= mon_minnum[this.getMonth().getValue()];
172 }
173 }
174 return false;
175 }//校验数据合法性
176
177 public void dayIncrement(){
178 this.value += 1;
179 if(this.getMonth().getYear().isLeapYear()){
180 if(this.value > mon_maxnum[this.getMonth().getValue()]){
181 this.resetMin();
182 }
183 }
184 else{
185 if(this.value > mon_minnum[this.getMonth().getValue()]){
186 this.resetMin();
187 }
188 }
189
190 }//日期+1
191
192 public void dayReduction(){
193 this.value -= 1;
194 if(value <1){
195 this.resetMax();
196 }
197
198 }//日期-1
199
200 public int getValue() {
201 return value;
202 }
203
204 public void setValue(int value) {
205 this.value = value;
206 }
207
208 public Month getMonth() {
209 return month;
210 }
211
212
213 }//日类
214
215 class Month{
216 private int value;
217 private Year year;
218
219 public Month(){
220
221 }
222
223 public Month(int yearValue,int monthValue) {
224 setValue(monthValue);
225 this.year = new Year(yearValue);
226 }
227 public void resetMin(){//月份复位(1)
228 this.value = 1;
229 this.getYear().yearIncrement();
230 }
231
232 public void resetMax(){//月份复位最大值
233 this.value = 12;
234 this.getYear().yearReduction();
235 }
236
237 public boolean validate(){
238 return this.getValue()>=1 && this.getValue() <=12;
239 }//校验数据合法性
240
241 public int getValue() {
242 return value;
243 }
244
245 public void setValue(int value) {
246 this.value = value;
247 }
248
249 public Year getYear() {
250 return year;
251 }
252
253 public void monthIncrement(){
254 this.value += 1;
255 if(value > 12){
256 this.resetMin();
257 }
258 }//月份+1
259 public void monthReduction(){
260 this.value -= 1;
261 if(value <1){
262 this.resetMax();
263 }
264 }//月份-1
265
266 }//月类
267
268 class Year{
269 private int value;
270
271 public Year(){
272
273 }
274 public Year(int value) {
275 setValue(value);
276 }
277
278 public boolean isLeapYear(){
279 return (getValue() % 4 == 0 && getValue() % 100 != 0) || getValue() % 400 == 0;
280 }//判断是否为闰年
281
282
283 public boolean validate(){//校验数据合法性
284 return this.getValue() >= 1900 && this.getValue() <= 2050;
285 }
286
287 public void yearIncrement(){
288 this.value++;
289 }//年份+1
290
291 public void yearReduction(){
292 this.value--;
293 }//年份-1
294
295 public int getValue() {
296 return value;
297 }
298
299 public void setValue(int value) {
300 this.value = value;
301 }
302 }//年类

点击这里查看代码

题目集5(7-4)

import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in); int choice = input.nextInt();
int d,m,y;
int n;
switch (choice){
case 1: //测试输入日期的后n天
y = input.nextInt();
m = input.nextInt();
d = input.nextInt();
n = input.nextInt();
DateUtil date1 = new DateUtil(d,m,y); if(date1.checkInputValidity()) {
System.out.print(date1.showDate()+" next " +n +" days is:");
date1 = date1.getNextNDays(n);
System.out.println(date1.showDate());
}
else
System.out.print("Wrong Format"); break;
case 2://测试输入日期的前n天
y = input.nextInt();
m = input.nextInt();
d = input.nextInt();
n = input.nextInt();
DateUtil date2 = new DateUtil(d,m,y); if(date2.checkInputValidity()) {
System.out.print(date2.showDate()+" previous "+n+" days is:");
date2 = date2.getPreviousDays(n);
System.out.println(date2.showDate());
}
else
System.out.print("Wrong Format");
break; case 3://测试两个日期之间相差的天数
y = input.nextInt();
m = input.nextInt();
d = input.nextInt();
DateUtil date3 = new DateUtil(d,m,y); y = input.nextInt();
m = input.nextInt();
d = input.nextInt();
DateUtil date4 = new DateUtil(d,m,y); int c;
if(date3.checkInputValidity() && date4.checkInputValidity()){
System.out.print("The days between "+date3.showDate());
c= date3.getDaysofDates(date4);
System.out.println(" and "+date4.showDate()+" are:"+c);
}
else
System.out.print("Wrong Format");
break; default:
System.out.print("Wrong Format"); }//选择功能主题
}
} class DateUtil{
private Day day;
private Month month;
private Year year;
int[] mon_minnum={0,31,28,31,30,31,30,31,31,30,31,30,31};//非闰年
int[] mon_maxnum={0,31,29,31,30,31,30,31,31,30,31,30,31};//闰年 public DateUtil(){ } public DateUtil(int d,int m,int y) {
this.day = new Day(d);
this.month = new Month(m);
this.year = new Year(y);
} public boolean checkInputValidity(){
return valiDay() && getMonth().validate() && getYear().validate(); }//校验数据合法性 public boolean compareDates(DateUtil date){
if(this.getYear().getValue() >date.getYear().getValue()) {
return true;
} else if(this.getYear().getValue() == date.getYear().getValue()&&this.getMonth().getValue() > date.getMonth().getValue()) {
return true;
} else return this.getYear().getValue() == date.getYear().getValue() && this.getMonth().getValue() == date.getMonth().getValue() && this.getDay().getValue() > date.getDay().getValue(); }//比较两个日期的大小,大则返回true,小为false public boolean equalTwoDates(DateUtil date){
return this.getDay().getValue() == date.getDay().getValue() && this.getMonth().getValue() == date.getMonth().getValue() && this.getYear().getValue() == date.getYear().getValue();
}//两个日期是否相等 public String showDate(){
return this.getYear().getValue()+"-"+this.getMonth().getValue()+"-"+this.getDay().getValue();
}//日期值格式化 public DateUtil getNextNDays(long n){//求下n天
for(int i =0; i<n;i++){
this.getDay().dayIncrement();
if(getYear().isLeapYear()){
if(getDay().getValue()>mon_maxnum[getMonth().getValue()]){
this.setDayMin();
if(getMonth().getValue()>12){
getMonth().resetMin();
getYear().yearIncrement();
}
}
}
else{
if(getDay().getValue()>mon_minnum[getMonth().getValue()]){
this.setDayMin();
if(getMonth().getValue()>12){
getMonth().resetMin();
getYear().yearIncrement();
}
}
}
}
return this;
} public DateUtil getPreviousDays(long n){//求前n天
for(int i =0; i<n;i++){
this.getDay().dayReduction();
if(getDay().getValue()<1){
setDayMax();
} }
return this;
} public int getDaysofDates(DateUtil date){//求两个日期之间的天数
int count=0;
if(!this.compareDates(date)){
while(!this.equalTwoDates(date)){
this.getDay().dayIncrement();
if(getYear().isLeapYear()){
if(getDay().getValue()>mon_maxnum[getMonth().getValue()]){
this.setDayMin();
if(getMonth().getValue()>12){
getMonth().resetMin();
getYear().yearIncrement();
}
}
}
else{
if(getDay().getValue()>mon_minnum[getMonth().getValue()]){
this.setDayMin();
if(getMonth().getValue()>12){
getMonth().resetMin();
getYear().yearIncrement();
}
}
}
count += 1; }
}
else{
while(!this.equalTwoDates(date)){
this.getDay().dayReduction();
if(getDay().getValue()<1){
setDayMax();
}
count += 1;
}
} return count;
} public void setDayMin(){
getDay().setValue(1);
this.getMonth().monthIncrement();
}//日复位 public void setDayMax(){
this.getMonth().monthReduction();
if(getMonth().getValue()<1){
getYear().yearReduction();
getMonth().resetMax();
}
if(this.getYear().isLeapYear())
getDay().setValue(mon_maxnum[this.getMonth().getValue()]);
else
getDay().setValue(mon_minnum[this.getMonth().getValue()]); }//日复位 public boolean valiDay(){
if(this.getMonth().validate()) {
if (this.getYear().isLeapYear()) {
return getDay().getValue() > 0 && getDay().getValue() <= mon_maxnum[this.getMonth().getValue()];
} else {
return getDay().getValue() > 0 && getDay().getValue() <= mon_minnum[this.getMonth().getValue()];
}
}
return false; } public Day getDay() {
return day;
} public void setDay(Day day) {
this.day = day;
} public Month getMonth() {
return month;
} public void setMonth(Month month) {
this.month = month;
} public Year getYear() {
return year;
} public void setYear(Year year) {
this.year = year;
}
} class Day{
private int value; public Day(){ } public Day(int value) {
setValue(value);
} public void dayIncrement(){
this.value += 1;
}//日期+1 public void dayReduction(){
this.value -= 1; }//日期-1 public int getValue() {
return value;
} public void setValue(int value) {
this.value = value;
} }//日类 class Month{
private int value; public Month(){ } public Month(int value) {
setValue(value);
}
public void resetMin(){//月份复位(1)
this.value = 1;
} public void resetMax(){//月份复位最大值
this.value = 12;
} public boolean validate(){
return this.getValue()>=1 && this.getValue() <=12;
}//校验数据合法性 public int getValue() {
return value;
} public void setValue(int value) {
this.value = value;
} public void monthIncrement(){
this.value += 1;
}//月份+1
public void monthReduction(){
this.value -= 1; }//月份-1 }//月类 class Year{
private int value; public Year(){ }
public Year(int value) {
setValue(value);
} public boolean isLeapYear(){
return (getValue() % 4 == 0 && getValue() % 100 != 0) || getValue() % 400 == 0;
}//判断是否为闰年 public boolean validate(){//校验数据合法性
return this.getValue() >= 1820 && this.getValue() <= 2020;
} public void yearIncrement(){
this.value++;
}//年份+1 public void yearReduction(){
this.value--;
}//年份-1 public int getValue() {
return value;
} public void setValue(int value) {
this.value = value;
}
}//年类

点击这里查看代码

  可以从代码和类图里看出,除了7-4中增加了一个计算天数的方法外,我的程序设计完全参考了题目要求中的类图设计(但我好像把聚合理解错了,但结果是好的)。在我查阅资料时,我曾看见过相关题目的解决思路,也曾一度让我想过要在计算两年之间天数时用一系列公式去计算该年的剩余天数。但在重新研究类图后我认为,类图中所提供的各种方法完全足够完成题目所要求的功能,所以我选择了放弃了手动计算,利用设计好的方法进行自动计算两年之间的天数,如下所示

 public int getDaysofDates(DateUtil date){//求两个日期之间的天数
int count=0;
if(!this.compareDates(date)){
while(!this.equalTwoDates(date)){
this.getDay().dayIncrement();
count += 1;
}
}
else{
while(!this.equalTwoDates(date)){
this.getDay().dayReduction();
count += 1;
}
}

求两个日期之间的天数

  


如果让我评价一下这两种类图设计思路的话,我认为各有各的好处

  7-2的方式可以在代码编写中快速且清晰的直接调用对应类的用法,基于是年月日逐个传递参数,所以可以将年月日进位的方法直接写入各自的类中,在DateUtil类中可以直接利用简单的循环对比日期去快速的获得两天之间的天数,年月日进位也交给了各自对应的类去处理。

  7-4的方式我还是保持了直接利用简单的循环对比日期去快速的获得两天之间的天数的思路,相比之下由于聚合设计的影响难以直接实现,举个例子,无法在Day类中直接调用Year类中对应的数值,所以只能将各种对应的进位方法写入DateUtil类中,导致该类中的代码看起来相对比较冗杂难懂,但相对的,Day类,Month类以及Year类的设计就可以最大的简化,仅仅只负责单纯的数值+1,而不用负责考虑该月的天数,该年是否为闰年,将所有的职责交给了DateUtil类


  复杂度分析:

7-2


7-4

可以从性能分析图中看到,这两个代码的圈复杂度不出意外的十分感人。

但如果结合代码不考虑主函数中三种不同操作导致的过高复杂度,程序整体的复杂度还是很客观的低于7,在程序设计时尽可能的做到一个方法完成一项职责,避免一个方法多个用法导致圈复杂度起飞


②题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)

老规矩先放代码和类图

7-3

  1 import java.util.Scanner;
2 import static java.lang.Math.*;
3
4
5 public class Main {
6 public static void main(String[] args) {
7 Scanner input = new Scanner(System.in);
8 int shapeType = input.nextInt();
9 switch (shapeType){
10 case 1:
11 double R1 = input.nextDouble();
12 if(R1<0)
13 System.out.println("Wrong Format");
14 else {
15 Circle c = new Circle();
16 c.setRadius(R1);
17 System.out.printf("Circle's area:%.2f%n", c.getArea());
18 }
19 break;
20 case 2:
21 double W1,L1;
22 W1 = input.nextDouble();
23 L1 = input.nextDouble();
24
25 if(W1<0||L1<0)
26 System.out.println("Wrong Format");
27 else {
28 Rectangle r = new Rectangle();
29 r.setWidth(W1);
30 r.setLength(L1);
31 System.out.printf("Rectangle's area:%.2f%n", r.getArea());
32 }
33
34 case 3:
35 double R2;
36 R2 = input.nextDouble();
37
38 if(R2<0)
39 System.out.println("Wrong Format");
40 else{
41 Ball b = new Ball();
42 b.setRadius(R2);
43 System.out.printf("Ball's surface area:%.2f%n",b.getArea());
44 System.out.printf("Ball's volume:%.2f%n",b.getVolume());
45 }
46 break;
47 case 4:
48 double W2,L2,H;
49 W2 = input.nextDouble();
50 L2 = input.nextDouble();
51 H = input.nextDouble();
52 if(W2 < 0||L2 < 0||H < 0)
53 System.out.println("Wrong Format");
54 else{
55 Box bx = new Box();
56 bx.setHeight(H);
57 bx.setLength(L2);
58 bx.setWidth(W2);
59
60 System.out.printf("Box's surface area:%.2f%n",bx.getArea());
61 System.out.printf("Box's volume:%.2f%n",bx.getVolume());
62 }
63
64 break;
65 default:
66 System.out.println("Wrong Format");
67
68 }
69 }
70 }
71
72
73 class Shape{
74 public Shape() {
75 System.out.println("Constructing Shape");
76 }
77
78 public double getArea(){
79 return 0.0;
80 }
81
82
83
84
85 }
86
87 class Circle extends Shape{
88 public Circle(){
89 System.out.println("Constructing Circle");
90 }
91
92 private double radius;
93
94 public double getRadius() {
95 return radius;
96 }
97
98 public void setRadius(double radius) {
99 this.radius = radius;
100 }
101
102 public double getArea(){
103 return PI * this.getRadius() * this.getRadius();
104 }
105 }
106
107 class Rectangle extends Shape{
108 public Rectangle(){
109 System.out.println("Constructing Rectangle");
110 }
111
112 private double width;
113 private double length;
114
115 public double getWidth() {
116 return width;
117 }
118
119 public void setWidth(double width) {
120 this.width = width;
121 }
122
123 public double getLength() {
124 return length;
125 }
126
127 public void setLength(double length) {
128 this.length = length;
129 }
130
131 public double getArea(){
132 return this.getWidth() * this.getLength();
133 }
134
135 }
136
137 class Ball extends Circle{
138 public Ball(){
139 System.out.println("Constructing Ball");
140 }
141
142 public double getArea(){
143 return 4.0 * super.getArea();
144 }
145
146 public double getVolume(){
147 return PI * pow(super.getRadius(),3)* 4.0/ 3.0;
148 }
149 }
150
151 class Box extends Rectangle{
152 public Box(){
153 System.out.println("Constructing Box");
154 }
155
156 private double height;
157
158 public double getHeight() {
159 return height;
160 }
161
162 public void setHeight(double height) {
163 this.height = height;
164 }
165
166 public double getArea(){
167 double w = super.getWidth();
168 double l = super.getLength();
169 double h = this.getHeight();
170
171 return 2 * (w * l + w * h + l * h);
172 }
173
174 public double getVolume(){
175 return this.getHeight() * super.getWidth() * super.getLength();
176 }
177 }

7-5

  1 import java.util.*;
2 public class Main {
3 public static void main(String[] args) {
4 Scanner input = new Scanner(System.in);
5 int a = input.nextInt();
6 int b = input.nextInt();
7 int c = input.nextInt();
8 ArrayList<Shape> shape = new ArrayList<>();
9 double totalArea = 0;
10
11 if(a < 0|| b < 0|| c < 0){
12 System.out.println("Wrong Format");
13 System.exit(0);
14 }
15
16
17
18
19 for(int i = 0; i<a;i++){
20 double r = input.nextDouble();
21 shape.add(new Circle(r));
22 }
23
24 for(int i = 0; i<b ; i++){
25 double w = input.nextDouble();
26 double l = input.nextDouble();
27 shape.add(new Rectangle(w,l));
28 }
29
30 for(int i = 0;i<c;i++){
31 double s1 = input.nextDouble();
32 double s2 = input.nextDouble();
33 double s3 = input.nextDouble();
34 shape.add(new Triangle(s1,s2,s3));
35 }
36
37
38 for (Shape value : shape) {
39 if (!value.validate()) {
40 System.out.println("Wrong Format");
41 System.exit(0);
42 } else
43 totalArea += value.getArea();
44 }
45
46 System.out.println("Original area:");
47 for(int i = 0 ; i<a+b+c;i++){
48 System.out.printf("%.2f ",shape.get(i).getArea());
49 }
50
51 System.out.printf("\nSum of area:%.2f\n",totalArea);
52
53 System.out.println("Sorted area:");
54
55 Shape temp;
56
57 for(int i = 0; i < shape.size()-1;i++){
58 for(int j = shape.size()-1; j>i;j--){
59 if(shape.get(j).getArea()<shape.get(j-1).getArea()) {
60 temp = shape.get(j);
61 shape.set(j, shape.get(j - 1));
62 shape.set(j - 1, temp);
63 }
64 }
65 }
66
67 for(int i = 0 ; i<a+b+c;i++){
68 System.out.printf("%.2f ",shape.get(i).getArea());
69 }
70
71 System.out.printf("\nSum of area:%.2f\n",totalArea);
72
73
74
75
76
77 }
78 }
79
80
81 abstract class Shape{
82 public abstract double getArea();
83
84 public abstract boolean validate();
85
86
87 }
88
89
90 class Circle extends Shape{
91 private double radius;
92
93 Circle(double radius){
94 setRadius(radius);
95 }
96
97 public double getArea(){
98 return Math.PI * radius * radius;
99 }
100
101 public boolean validate(){
102 return getRadius() >0;
103 }
104
105
106
107
108
109 public double getRadius() {
110 return radius;
111 }
112
113 public void setRadius(double radius) {
114 this.radius = radius;
115 }
116 }
117
118 class Rectangle extends Shape{
119 private double width;
120 private double length;
121
122 Rectangle(double width,double length){
123 setWidth(width);
124 setLength(length);
125 }
126
127 public double getArea(){
128 return getLength() * getWidth();
129 }
130
131 public boolean validate(){
132 return (getWidth() >0 && getLength()>0);
133 }
134
135
136
137 public double getWidth() {
138 return width;
139 }
140
141 public void setWidth(double width) {
142 this.width = width;
143 }
144
145 public double getLength() {
146 return length;
147 }
148
149 public void setLength(double length) {
150 this.length = length;
151 }
152 }
153
154 class Triangle extends Shape{
155 private double side1;
156 private double side2;
157 private double side3;
158
159
160 Triangle(double side1,double side2,double side3){
161 setSide1(side1);
162 setSide2(side2);
163 setSide3(side3);
164 }
165
166
167 public double getArea(){
168 double p=(side1+side2+side3)/2;
169 return Math.sqrt(p*(p-side1)*(p-side2)*(p-side3));
170 }
171
172 public boolean validate(){
173 if(side1+side2<=side3||side1+side3<=side2||side2+side3<=side1)
174 {
175 return false;
176 }
177 return !(side1 - side2 >= side3) && !(side1 - side3 >= side2) && !(side2 - side3 >= side1);
178 }
179
180
181
182 public void setSide1(double side1) {
183 this.side1 = side1;
184 }
185
186
187 public void setSide2(double side2) {
188 this.side2 = side2;
189 }
190
191
192
193 public void setSide3(double side3) {
194 this.side3 = side3;
195 }
196 }

7-6

 1 import java.util.*;
2
3 public class Main {
4 public static void main(String[] args) {
5 Scanner input = new Scanner(System.in);
6 double radius,width,length;
7 radius = input.nextDouble();
8 width = input.nextDouble();
9 length = input.nextDouble();
10 Rectangle rec = new Rectangle(width,length);
11 Circle cir = new Circle(radius);
12 if(rec.getLength() <= 0||rec.getWidth() <= 0 || cir.getRadius() <=0){
13 System.out.println("Wrong Format");
14 System.exit(0);
15 }
16 else{
17 System.out.printf("%.2f\n",cir.getArea());
18 System.out.printf("%.2f",rec.getArea());
19 }
20
21
22 }
23 }
24
25 class Rectangle implements GetArea{
26 private double width;
27 private double length;
28
29 Rectangle(){}
30
31 Rectangle(double width,double length){
32 setWidth(width);
33 setLength(length);
34 }
35
36 public double getArea(){
37 return width * length;
38 }
39
40 public double getWidth() {
41 return width;
42 }
43
44 public void setWidth(double width) {
45 this.width = width;
46 }
47
48 public double getLength() {
49 return length;
50 }
51
52 public void setLength(double length) {
53 this.length = length;
54 }
55 }
56
57 class Circle implements GetArea{
58 private double radius;
59 Circle(){}
60
61 Circle(double radius){
62 setRadius(radius);
63 }
64
65 public double getArea(){
66 return Math.PI * radius * radius;
67 }
68
69 public double getRadius() {
70 return radius;
71 }
72
73 public void setRadius(double radius) {
74 this.radius = radius;
75 }
76 }
77
78 interface GetArea{
79 double getArea();
80 }


  在7-3中,主要考察了继承的使用以及简单多态的应用,通过对父类方法的继承,并在子类中定义同名的方法,对父类的方法进行重写,并将对应的方法继承给子类的子类,以达成多态的使用效果

  在7-5中,我尝试使用了抽象类的方式完成需求,通过父类的抽象,并在子类中对对应的抽象方法进行定义,以此更加便捷的实现多态

  在7-6中,我第一次尝试使用了接口,在查阅资料后得知,接口默认为一个抽象类,其中所有的方法会被默认为一个抽象方法,并且该接口无法实例化,仅用于类似抽象类的重写以完成各种不同的需求


复杂度分析

7-3

7-5

7-6


  如上图,我在构思该题目的解决方案时,主要目的是完成java的封装、继承、多态、接口等,并未刻意对代码的圈复杂度进行过多的思考与优化,故代码的圈复杂度达到了10+


③对三次题目集中用到的正则表达式技术的分析总结

  在这三次题目集中有使用到正则表达式的题目有

第4次作业 7-1 水文数据校验及处理  第5次作业7-4 统计Java程序中关键词的出现次数  第6次作业7-1至7-4

在这些题目中可以很明显的感觉到前二者的难度远超第六次作业的四题,第6次作业的题目相较于前者,更偏向于基础运用,而前者则属于实际需求应用,这一点也可以很清楚的从相应的正则表达式中得以体现

4-7-1

String regex1="(((([1-9])|([1-9][0-9])|([1-9][0-9]{2})|([1-9][0-9]{3})/((([13578]|1[02])/([1-9]|[12][0-9]|3[01]))|(([469]|11)/([1-9]|[12][0-9]|30))|(2/([1-9]|[1][0-9]|2[0-8])))))|(((([1-9][0-9])(0[48]|[2468][048]|[13579][26]))|(([48]|[2468][048]|[3579][26])00))/2/29)) ((([02468])|(1[02468])|(2[02])):00)";//时间合法
String regex2="([1-9][0-9]{0,2}(\\.[0-9]{1,3})?)";//水位、流量合法
String regex3="[1-9]\\.\\d{2}";//开度合法

4-7-1

5-7-4

sb.append(s.replaceAll("//.*", "").replaceAll("\".*\"", "").replaceAll("\\[.*]","").replaceAll("=null","")).append(" ");//不接受注释内容,不接受引号内内容,并用空格分割代码
s = input.nextLine(); }
code = sb.toString().replaceAll("/\\*\\s*.*\\s*\\*/", " "); if (code.isEmpty()) {//未输入源码
System.out.println("Wrong Format");
}
else {
for (String value : key) {//比较关键词,并存入map中
int n = 0;
Pattern pattern = Pattern.compile("\\b" + value + "\\b");//编译关键词样板

5-7-4

6-7-4

Pattern pattern = Pattern.compile("2020(1[1-7]|61|7[1-3]|8[1-2])(0[1-9]|[1-3][0-9]|40)");
Matcher matcher = pattern.matcher(s);

6-7-4

  通过这三次作业对正则表达式的相关使用,以及上一次BLOG中所遇见的正则表达式题目,使我能够相对熟练的使用正则表达式去匹配特定的字符串/数字,并通过matcher等相关方法去对输入数据进行查找匹配,以此完成各类复杂的需求


④题目集5(7-4)中Java集合框架应用的分析总结

首先是安排上代码

 1 import java.util.*;
2 import java.util.regex.Matcher;
3 import java.util.regex.Pattern;
4
5 public class Main {
6 public static void main(String[] args) {
7 Scanner input = new Scanner(System.in);
8 StringBuilder sb = new StringBuilder();
9 String code;
10 Map<String, Integer> map = new TreeMap<>();
11 String[] key = {"abstract", "assert", "boolean", "break", "byte", "case", "catch",
12 "char", "class", "const", "continue", "default", "do", "double", "else",
13 "enum", "extends", "false", "final", "finally", "float",
14 "for", "goto", "if", "implements", "import", "instanceof",
15 "int", "interface", "long", "native", "new", "null", "package",
16 "private", "protected", "public", "return", "short", "static",
17 "strictfp", "super", "switch", "synchronized", "this", "throw",
18 "throws", "transient", "true", "try", "void", "volatile", "while"};
19
20 String s = input.nextLine();
21 while (!s.equals("exit")) {
22 if (s.length() == 0) {//不接受空行
23 s = input.nextLine();
24 continue;
25 }
26
27 sb.append(s.replaceAll("//.*", "").replaceAll("\".*\"", "").replaceAll("\\[.*]","").replaceAll("=null","")).append(" ");//不接受注释内容,不接受引号内内容,并用空格分割代码
28 s = input.nextLine();
29
30 }
31 code = sb.toString().replaceAll("/\\*\\s*.*\\s*\\*/", " ");
32
33 if (code.isEmpty()) {//未输入源码
34 System.out.println("Wrong Format");
35 }
36 else {
37 for (String value : key) {//比较关键词,并存入map中
38 int n = 0;
39 Pattern pattern = Pattern.compile("\\b" + value + "\\b");//编译关键词样板
40 Matcher matcher = pattern.matcher(code);
41 while (matcher.find()) {
42 n++;
43 }
44 if (n != 0) {
45 map.put(value, n);
46 }
47 }
48 }
49
50 for (String s2 : map.keySet()) {//按格式输出
51 System.out.println(map.get(s2) + "\t" + s2);
52 }
53 }
54
55
56 }

  

集合可以看作是一种容器,用来存储对象信息。所有集合类都位于java.util包下,但支持多线程的集合类位于java.util.concurrent包下。

  数组与集合的区别如下:

  1)数组长度不可变化而且无法保存具有映射关系的数据;集合类用于保存数量不确定的数据,以及保存具有映射关系的数据。

  2)数组元素既可以是基本类型的值,也可以是对象;集合只能保存对象。

  Java集合类主要由两个根接口Collection和Map派生出来的,Collection派生出了三个子接口:List、Set、Queue(Java5新增的队列),因此Java集合大致也可分成List、Set、Queue、Map四种接口体系,(注意:Map不是Collection的子接口)。

  其中List代表了有序可重复集合,可直接根据元素的索引来访问;Set代表无序不可重复集合,只能根据元素本身来访问;Queue是队列集合;Map代表的是存储key-value对的集合,可根据元素的key来访问value。

  在本题中,参考解题报告中的要求,我选择了使用Map接口用于记录Matcher所匹配到的java关键字,但在本次作业前我并未对此进行过相关学习,在查阅资料后得知Map接口采用键值对Map<K,V>的存储方式,保存具有映射关系的数据,因此,Map集合里保存两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value,key和value可以是任意引用类型的数据。key值不允许重复,可以为null。如果添加key-value对时Map中已经有重复的key,则新添加的value会覆盖该key原来对应的value。常用实现类有HashMap、LinkedHashMap、TreeMap等。

  在实际操作中,我选择了使用TreeMap来记录数据,由于TreeMap是SortedMap的实现类,是一个红黑树的数据结构,每个key-value对作为红黑树的一个节点。TreeMap存储key-value对时,需要根据key对节点进行排序,所以可以保证记录关键字的顺序。并通过.put()及.get()等相关方法对集合进行存取。


  (3)踩坑心得

  怎么说呢,在这几次作业里不仅仅是用到了上课时老师教过的各类知识,还在题目中要求了我们使用各种从未听说过的接口、方法(如Map),这让我意识到了上课所教授的内容远远不足以支持我后续的学习与工作,这也更意味着自己查阅资料的重要性,知识是一片汪洋,永远也没有枯竭的那一天,只能说学无止境吧。


  (4)总结

  通过这三次作业的“洗礼”,我深刻意识到自己是个菜鸡,好几道题目不了了之,由于过于依赖搜索引擎去寻找思路,陷入他人想法的思维定势中,最后的查重结果也让我不是很能接受,在OOP学习花费的时间越多,越能意识到这一种编程思想不是那么容易掌握的。各种编程的基本准则也难以在我的代码体现出来,希望自己在后续的学习中能够精进自己的技术,学会各种全新的知识,查重率也有能不要再飘黄了

题目集4~6的总结性Blog的相关教程结束。

《题目集4~6的总结性Blog.doc》

下载本文的Word格式文档,以方便收藏与打印。