首页 > 其他分享 >题目集4,5,6的总结

题目集4,5,6的总结

时间:2023-04-30 15:33:25浏览次数:39  
标签:总结 题目 int getValue getYear date day getMonth

前言:一步错步步错,学习这个循环渐进的过程任何跳步骤的行为都会导致严重的后果。从题目集4开始我就进入了一个非要痛彻心扉改过不可的循环,一个发现困难——放弃——成绩不能达标——发现困难的循环。从题目集4开始题目难度就明显上升,其中的题目1就好像是突然把小坡的坡度加高到小山(这种感觉没错,后来我发现这一题和求日期一样是一个迭代的问题,而我们前面的两次迭代都没有参与,题目集4的题目1是第三次迭代),我光是看到那长长的题目描述就心生退意,更别说后面的题目也并非很容易就能写出,最后这一题被我完全放弃。但是,报应不爽,在题目集6它又来了,它披坚执锐,比前面更难对付,而我前面与它未曾打过交道,更是难以找到破除它防御的方法。情况已经很危急了。

这三次题目集开始我们小试牛刀,感受面向对象编程的一大特性:封装,自此之后,Java与c语言的不同更加明显,一道题不再是一个Main方法可以写出来的了;练习聚合组合的用法,即便一道题目两种写法同是聚合,两者也有相当大的差别;也学习使用了正则表达式,正则表达式不仅在Java里面存在,还存在在好几种语言中,不管是linux,python,c++都可以使用,学会它与我们来说非常必要,是需要花时间去理解和简单记忆的。

在题量方面,这三次题目集的题目都不多,特别是第六次,更是只有一题;但是题目的难度和题量成反比,因为我的日期类题目都写出来了,正则表达式类题目只要找到诀窍,题目都是一样的写法,我自我感觉第四次和第六次题目非常难。

设计和分析

题目集4的7-1

诚恳地,抱歉地说,我这道题是没怎么写的,因为题目集6的7-1是它的迭代,我的分析就不在这里赘述,都在下面的题目集6的7-1。

题目集5的7-5

7-5 日期问题面向对象设计(聚合一)

分数 50

全屏浏览题目

作者 段喜龙

单位 南昌航空大学

参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

 

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

输入格式:

有三种输入方式(以输入的第一个数字划分[1,3]):

  • 1 year month day n //测试输入日期的下n天
  • 2 year month day n //测试输入日期的前n天
  • 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
  • 当输入有误时,输出格式如下:
    Wrong Format
    • 当第一个数字为1且输入均有效,输出格式如下:

输出格式:

year-month-day

  • 当第一个数字为2且输入均有效,输出格式如下:

year-month-day

  • 当第一个数字为3且输入均有效,输出格式如下:

天数值

题目如上,我的代码如下:

  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 year = 0;
  7         int month = 0;
  8         int day = 0;
  9 
 10         int choice = input.nextInt();
 11 
 12         if (choice == 1) { // test getNextNDays method
 13             int m = 0;
 14             year = Integer.parseInt(input.next());
 15             month = Integer.parseInt(input.next());
 16             day = Integer.parseInt(input.next());
 17 
 18             DateUtil date = new DateUtil(year, month, day);
 19 
 20             if (!date.checkInputValidity()) {
 21                 System.out.println("Wrong Format");
 22                 System.exit(0);
 23             }
 24 
 25             m = input.nextInt();
 26 
 27             if (m < 0) {
 28                 System.out.println("Wrong Format");
 29                 System.exit(0);
 30             }
 31 
 32             System.out.println(date.getNextNDays(m).showDate());
 33         } else if (choice == 2) { // test getPreviousNDays method
 34             int n = 0;
 35             year = Integer.parseInt(input.next());
 36             month = Integer.parseInt(input.next());
 37             day = Integer.parseInt(input.next());
 38 
 39             DateUtil date = new DateUtil(year, month, day);
 40 
 41             if (!date.checkInputValidity()) {
 42                 System.out.println("Wrong Format");
 43                 System.exit(0);
 44             }
 45 
 46             n = input.nextInt();
 47 
 48             if (n < 0) {
 49                 System.out.println("Wrong Format");
 50                 System.exit(0);
 51             }
 52 
 53             System.out.println(date.getPreviousNDays(n).showDate());
 54         } else if (choice == 3) {    //test getDaysofDates method
 55             year = Integer.parseInt(input.next());
 56             month = Integer.parseInt(input.next());
 57             day = Integer.parseInt(input.next());
 58 
 59             int anotherYear = Integer.parseInt(input.next());
 60             int anotherMonth = Integer.parseInt(input.next());
 61             int anotherDay = Integer.parseInt(input.next());
 62 
 63             DateUtil fromDate = new DateUtil(year, month, day);
 64             DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
 65 
 66             if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
 67                 System.out.println( fromDate.getDaysofDates(toDate));
 68             } else {
 69                 System.out.println("Wrong Format");
 70                 System.exit(0);
 71             }
 72         }
 73         else{
 74             System.out.println("Wrong Format");
 75             System.exit(0);
 76         }
 77     }
 78 }
 79 
 80 class DateUtil{
 81     private Day day = new Day();
 82     public DateUtil(){
 83 
 84     }
 85     public DateUtil(int d,int m, int y){
 86         int t = 0;
 87         t = d;
 88         d = y;
 89         y = t;
 90         this.getDay().setValue(d);
 91         this.day.getMonth().setValue(m);
 92         this.day.getMonth().getYear().setValue(y);
 93     }
 94     //day getter
 95     public Day getDay() {
 96         return day;
 97     }
 98     //day setter
 99     public void setDay(Day d) {
100         this.day = d;
101     }
102     //date校验数据合法性
103     public boolean checkInputValidity(){
104         return (this.day.getMonth().getYear().validate() && this.day.getMonth().validate() && this.day.validate());
105     }
106     //比较两个日期的大小
107     public boolean compareDates(DateUtil date){//前一个日期在前正确
108         if(this.day.getMonth().getYear().getValue() - date.day.getMonth().getYear().getValue() > 0){//先判断年份
109             return false;
110         }else if(this.day.getMonth().getYear().getValue() - date.day.getMonth().getYear().getValue() < 0){
111             return true;
112         }else if(this.day.getMonth().getYear().getValue() - date.day.getMonth().getYear().getValue() == 0){//年份相同的情况下
113             if(this.day.getMonth().getValue() - date.day.getMonth().getValue() > 0){//再判断月份
114                 return false;
115             }else if(this.day.getMonth().getValue() - date.day.getMonth().getValue() < 0){
116                 return true;
117             }else //月份相同的情况下
118                 if(this.day.getMonth().getValue() - date.day.getMonth().getValue() == 0)
119                     if (this.day.getValue() - date.day.getValue() > 0) {//最后判断日子
120                         return false;
121                     } else if (this.day.getValue() - date.day.getValue() < 0) {
122                         return true;
123                     }
124         }
125         return true;
126     }
127     //判定两个日期是否相等
128     public boolean equalTwoDates(DateUtil date){//年,月,日一一对应正确
129         return this.day.getMonth().getYear().getValue() == date.day.getMonth().getYear().getValue() && this.day.getMonth().getValue() == date.day.getMonth().getValue() && this.day.getValue() == date.day.getValue();
130     }
131     //日期值格式化
132     public String showDate(){
133         return (this.day.getMonth().getYear().getValue() + "-" + this.day.getMonth().getValue() + "-" + this.day.getValue());
134     }
135     //求下n天
136     public DateUtil getNextNDays(int n){
137         //计算当前日期在一年里的第几天
138         int sum = 0,daysum = 0;
139         if (this.day.getMonth().getValue() - 1 == 0){
140             this.day.getMonth().monthReduction();
141         }
142         for(int i = 0; i < this.day.getMonth().getValue() - 1; i++){
143             if(this.day.getMonth().getYear().isLeapYear(this.day.getMonth().getYear().getValue())){
144                 this.day.getMon_maxnum()[1] = 29;
145             }else this.day.getMon_maxnum()[1] = 28;
146             sum += this.day.getMon_maxnum()[i];
147         }
148         sum += this.day.getValue();
149         //计算下个日期的年份
150         sum += n;
151         if(this.day.getMonth().getYear().isLeapYear(this.day.getMonth().getYear().getValue())){
152             daysum = 366;
153         }else{
154             daysum = 365;
155         }
156         while (sum - daysum > 0){//daysum==0
157             if(this.day.getMonth().getYear().isLeapYear(this.day.getMonth().getYear().getValue())){
158                 daysum = 366;
159             }else{
160                 daysum = 365;
161             }
162             sum = sum-daysum;
163             //this.year ++;
164             this.day.getMonth().getYear().yearIncrement();
165             //this.month = 1;
166             this.day.getMonth().resetMin();
167         }
168         if(this.day.getMonth().getYear().isLeapYear(this.day.getMonth().getYear().getValue())){
169             this.day.getMon_maxnum()[1] = 29;
170         }else{
171             this.day.getMon_maxnum()[1] = 28;
172         }
173         //sum是月与日
174         if(sum > this.day.getMon_maxnum()[0]) {//计算月日
175             for (int i = 0; sum > this.day.getMon_maxnum()[i]; i++) {
176                 sum = sum - this.day.getMon_maxnum()[i];
177                 this.day.getMonth().setValue(i);
178             }
179             this.day.getMonth().monthIncrement();
180         }
181         this.day.setValue(sum);
182         this.day.getMonth().monthIncrement();
183         return this;
184     }
185     //求前n天
186     public DateUtil getPreviousNDays(int n){
187         //计算当前日期在一年里的第几天
188         int sum = 0,daysum = 0;
189         for(int i = 0; i < this.day.getMonth().getValue() - 1; i ++){
190             if(this.day.getMonth().getYear().isLeapYear(this.day.getMonth().getYear().getValue())){
191                 this.day.getMon_maxnum()[1] = 29;
192             }else this.day.getMon_maxnum()[1] = 28;
193             sum += this.day.getMon_maxnum()[i];
194         }
195         sum += this.day.getValue();
196         //计算下一个日期
197         sum -= n;
198         if(sum<0){//跨年了
199             if(this.day.getMonth().getYear().isLeapYear(this.day.getMonth().getYear().getValue()-1)){
200                 daysum = 366;
201             }else{
202                 daysum = 365;
203             }//计算年份
204             while (sum+daysum<0){
205                 if(this.day.getMonth().getYear().isLeapYear(this.day.getMonth().getYear().getValue()-1)){
206                     daysum = 366;
207                 }else{
208                     daysum = 365;
209                 }
210                 sum = sum+daysum;
211                 this.day.getMonth().getYear().yearReduction();
212             }//计算正数的月份
213             //this.year = this.year-1;
214             this.day.getMonth().getYear().yearReduction();
215             if(this.day.getMonth().getYear().isLeapYear(this.day.getMonth().getYear().getValue())){
216                 daysum = 366;
217             }else{
218                 daysum = 365;
219             }
220             sum = daysum+sum;
221         }
222         if(this.day.getMonth().getYear().isLeapYear(this.day.getMonth().getYear().getValue())){
223             this.day.getMon_maxnum()[1] = 29;
224         }else{
225             this.day.getMon_maxnum()[1] = 28;
226         }
227         //计算月份
228         if(sum > this.day.getMon_maxnum()[0]) {//计算月日
229             for (int i = 0; sum > this.day.getMon_maxnum()[i]; i ++) {
230                 sum = sum - this.day.getMon_maxnum()[i];
231                 //this.month = i;
232                 this.day.getMonth().setValue(i);
233             }
234             this.day.getMonth().monthIncrement();
235         }
236         this.day.setValue(sum);
237         this.day.getMonth().monthIncrement();
238         return this;
239     }
240     //求两个日期之间的天数
241     public int getDaysofDates(DateUtil date){
242         int n = 0;
243         if(equalTwoDates(date)){
244             return 0;
245         }else {
246             int k = 0;
247             //保证第一个日期始终在前
248             if (!compareDates(date)) {
249                 k = this.day.getMonth().getYear().getValue();
250                 this.day.getMonth().getYear().setValue(date.day.getMonth().getYear().getValue());
251                 date.day.getMonth().getYear().setValue(k);
252                 k = this.day.getMonth().getValue();
253                 this.day.getMonth().setValue(date.day.getMonth().getValue());
254                 date.day.getMonth().setValue(k);
255                 k = this.day.getValue();
256                 this.day.setValue(date.day.getValue());
257                 date.day.setValue(k);
258             }
259             //计算两个日期相差天数
260             //计算两个日期在一年里的位置
261             int sum1 = 0, daysum = 0, sum2 = 0;
262             for (int i = 0; i < this.day.getMonth().getValue() - 1; i ++) {
263                 if (this.day.getMonth().getYear().isLeapYear(this.day.getMonth().getYear().getValue())) {
264                     this.day.getMon_maxnum()[1] = 29;
265                 }
266                 else this.day.getMon_maxnum()[1] = 28;
267                 sum1 += this.day.getMon_maxnum()[i];
268             }
269             sum1 += this.day.getValue();
270 
271             for (int i = 0; i < date.day.getMonth().getValue() - 1; i++) {
272                 if (this.day.getMonth().getYear().isLeapYear(date.day.getMonth().getYear().getValue())) {
273                     this.day.getMon_maxnum()[1] = 29;
274                 }
275                 else this.day.getMon_maxnum()[1] = 28;
276                 sum2 += this.day.getMon_maxnum()[i];
277             }
278             sum2 += date.day.getValue();
279             //n = sum2 - sum1;//计算一年里两个日期的差
280             //计算两个日期相差的年份
281             for (; this.day.getMonth().getYear().getValue() <= date.day.getMonth().getYear().getValue();) {
282                 n += daysum;
283                 if (this.day.getMonth().getYear().isLeapYear(this.day.getMonth().getYear().getValue())) {
284                     daysum = 366;
285                 } else {
286                     daysum = 365;
287                 }
288                 this.day.getMonth().getYear().yearIncrement();
289             }
290             n = n - sum1 +sum2;
291         }
292         return n;
293     }
294 }
295 class Day{
296     private int value;
297     private Month month = new Month();
298     private int[] mon_maxnum = {31,28,31,30,31,30,31,31,30,31,30,31};
299     public Day(){
300 
301     }
302     public Day(int yearValue, int monthValue, int dayValue){
303         this.value = dayValue;
304         this.getMonth().setValue(monthValue);
305         this.month.getYear().setValue(yearValue);
306     }
307 
308     public int[] getMon_maxnum() {
309         return mon_maxnum;
310     }
311 
312     //day value getter
313     public int getValue() {
314         return value;
315     }
316     //day value setter
317     public void setValue(int value) {
318         this.value = value;
319     }
320     //day month getter
321     public Month getMonth() {
322         return month;
323     }
324     //day month setter
325     public void setMonth(Month value) {
326         this.month = value;
327     }
328     //day 日期复位(1)
329     public void resetMin(){
330         this.value = 1;
331     }
332     //day 日期设为该月最大值
333     public void resetMax(){
334         this.value = mon_maxnum[this.month.getValue()];
335     }
336     //day校验数据合法性
337     public boolean validate(){
338         if (this.month.getYear().isLeapYear(this.month.getYear().getValue())){
339             mon_maxnum[1] += 1;
340         }
341         if (this.value > mon_maxnum[this.month.getValue() - 1] || this.value < 1){
342             return false;
343         }else return true;
344     }
345     //日期增1
346     public void dayIncrement(){
347         this.value ++;
348     }
349     //日期减1
350     public void dayReduction(){
351         this.value --;
352     }
353 }
354 class Month{
355     private int value;
356     private Year year = new Year();
357     public Month(){
358 
359     }
360     public Month(int yearValue,int monthValue){
361         this.value = monthValue;
362         this.getYear().setValue(yearValue);
363     }
364     //month value getter
365     public int getValue() {
366         return value;
367     }
368     //month value setter
369     public void setValue(int value) {
370         this.value = value;
371     }
372     //month year getter
373     public Year getYear() {
374         return year;
375     }
376     //month year setter
377     public void setYear(Year year) {
378         this.year = year;
379     }
380     //月份复位(1)
381     public void resetMin(){
382         this.value = 1;
383     }
384     //月份设置为12
385     public void resetMax(){
386         this.value = 12;
387     }
388     //month校验数据合法性
389     public boolean validate(){
390         return (this.value >= 1 && this.value <= 12);
391     }
392     //月份增1
393     public void monthIncrement(){
394         this.value ++;
395     }
396     //月份减1
397     public void monthReduction(){
398         this.value --;
399     }
400 }
401 class Year{
402     private int value;
403     public Year(){
404 
405     }
406     public Year(int value){
407         this.value = value;
408     }
409     //year value getter
410     public int getValue() {
411         return value;
412     }
413     //year value setter
414     public void setValue(int value) {
415         this.value = value;
416     }
417     //判断是否为闰年
418     public boolean isLeapYear(int value){
419         return ((value % 400 == 0) || (value % 4 == 0 && value % 100 != 0));
420     }
421     //year校验数据合法性
422     public boolean validate(){
423         return (this.value >= 1900 && this.value <= 2050);
424     }
425     //年份增1
426     public void yearIncrement(){
427         this.value ++;
428     }
429     //年份减1
430     public void yearReduction(){
431         this.value --;
432     }
433 }

 

用PowerDesigner生成的图像:

 

 

用SourceMonitor生成图像:

分析:设计类图老师已经交给了我们,这题需要我们定义四个类,和上一次迭代相比,DateUtil不再做所有的工作,而是把工作分给了新类Day,Month,Year,比如判断是否为闰年的方法isLeapYear()成为Year类独有的,加一天减一天dayIncrement(),dayReduction()这样的小代码也被独立出来成为一个方法在Day类里面,这么做是为了实现单一职责原则,让Main类和DataUtil类不要做太多事,达成容易找到错误,代码易修改的成就,如果一个代码块过长,功能过多,代码的方法就像海藻一样纠缠在一起就不容易查找bug,找到后也很难去修改,后期难以维护,如果将代码块截成一个一个小块,使用的时候用统一的引用方法(例如date.getDay()),那么假使真的代码有错,只要修改小代码块的部分就可以,所有的引用(date.getDay())是不用动的,比不按这种方法写就得查找每一行代码看是否有错要来得轻松的多。说完聚合的好处,再说怎么样实现聚合。在DateUtil类里面有Day属性,在Day类里面有Month属性,在Month类里面有Year属性。也就是说Month可以调用Year里面的方法,Day可以调用Month里面的方法,DateUtil可以调用Day里面的方法,主方法与DateUtil联系紧密,它们形成了一条调用方法的链,按照这个类图的特性来说类图里面两个类只要间隔一个类那么它们就不能直接沟通,前面的不能直接调用后面的方法,只有通过中间的类辅助才可以,也就是说如果在主方法里面需要判断一年是否是闰年,用到Year类的isLeapYear方法,直接写isLeapYear(某年)是不可行的,而应该要在Main类里面定义一个DateUtil属性的date;再写date.getDay().getMonth().getYear().isLeapYear(某年)才可以,当然这是例子,实际上Main类根本就不会用到isLeapYear()方法,为了落实单一职责,它只会引用到DateUtil的showDate()方法,具体有关时间的计算,各种调用还是在DateUtil类里实现的,应该说除了处于最底层的Year类,其他几个类都会或多或少实现调用。

从我自己的代码生成的类图分析:

我不清楚是类图生成有误还是什么,我的类图把聚合关系变成了关联,按理说聚合的实现方法就是在一个类里面私有化另一个类对象,加诸另一个类的setter和getter方法,以setter和getter方法为媒介使一个类可以通过该私有化对象调用另一个类的方法,而我就是这样写的,却没得到聚合的结果。不过,链式结构是没错的。因为有老师的类图指导,结果和老师的类图也类似。

从SourceMonitor来看,我的代码还是那些问题,毕竟也就是之前写过了的日期类题目稍加改动得到的,我的代码Max Complexity超过绿色区域,Avg Complexity却不在绿色范围内,应该是给DateUtil类的任务太重了,导致DateUtil的圈复杂度非常大,if-else语句太多了。

题目集5的7-6

题目如下:

7-6 日期问题面向对象设计(聚合二) 分数 34 作者 段喜龙 单位 南昌航空大学

参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

类图.jpg

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

我的代码如下:

  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 = 0;
  6         int month = 0;
  7         int day = 0;
  8 
  9         int choice = input.nextInt();
 10 
 11         if (choice == 1) { // test getNextNDays method
 12             int m = 0;
 13             year = Integer.parseInt(input.next());
 14             month = Integer.parseInt(input.next());
 15             day = Integer.parseInt(input.next());
 16 
 17             DateUtil date = new DateUtil(year, month, day);
 18 
 19             if (!date.checkInputValidity()) {
 20                 System.out.println("Wrong Format");
 21                 System.exit(0);
 22             }
 23 
 24             m = input.nextInt();
 25 
 26             if (m < 0) {
 27                 System.out.println("Wrong Format");
 28                 System.exit(0);
 29             }
 30 
 31             System.out.print(date.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " next " + m + " days is:");
 32             System.out.println(date.getNextNDays(m).showDate());
 33         } else if (choice == 2) { // test getPreviousNDays method
 34             int n = 0;
 35             year = Integer.parseInt(input.next());
 36             month = Integer.parseInt(input.next());
 37             day = Integer.parseInt(input.next());
 38 
 39             DateUtil date = new DateUtil(year, month, day);
 40 
 41             if (!date.checkInputValidity()) {
 42                 System.out.println("Wrong Format");
 43                 System.exit(0);
 44             }
 45 
 46             n = input.nextInt();
 47 
 48             if (n < 0) {
 49                 System.out.println("Wrong Format");
 50                 System.exit(0);
 51             }
 52 
 53             System.out.print(date.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " previous " + n + " days is:");
 54             System.out.println(date.getPreviousNDays(n).showDate());
 55         } else if (choice == 3) {    //test getDaysofDates method
 56             year = Integer.parseInt(input.next());
 57             month = Integer.parseInt(input.next());
 58             day = Integer.parseInt(input.next());
 59 
 60             int anotherYear = Integer.parseInt(input.next());
 61             int anotherMonth = Integer.parseInt(input.next());
 62             int anotherDay = Integer.parseInt(input.next());
 63 
 64             DateUtil fromDate = new DateUtil(year, month, day);
 65             DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
 66 
 67             if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
 68                 System.out.println("The days between " + fromDate.showDate() +
 69                         " and " + toDate.showDate() + " are:"
 70                         + fromDate.getDaysofDates(toDate));
 71             } else {
 72                 System.out.println("Wrong Format");
 73                 System.exit(0);
 74             }
 75         }
 76         else{
 77             System.out.println("Wrong Format");
 78             System.exit(0);
 79         }
 80     }
 81 }
 82 
 83 class DateUtil{
 84     private Year year = new Year();
 85     private Month month = new Month();
 86     private Day day = new Day();
 87     private int[] mon_maxnum = {31,28,31,30,31,30,31,31,30,31,30,31};
 88     public DateUtil(){
 89 
 90     }
 91     public DateUtil(int y,int m, int d) {
 92         this.getYear().setValue(y);
 93         this.getMonth().setValue(m);
 94         this.getDay().setValue(d);
 95     }
 96     public void setYear(Year year) {
 97         this.year = year;
 98     }
 99 
100     public Year getYear() {
101         return year;
102     }
103 
104     public Month getMonth() {
105         return month;
106     }
107 
108     public void setMonth(Month month) {
109         this.month = month;
110     }
111 
112     public Day getDay() {
113         return day;
114     }
115 
116     public void setDay(Day day) {
117         this.day = day;
118     }
119     //设置日期最小值(1)
120     public void setDayMin(){
121         int dayMin = 1;
122     }
123     //设置日期最大值(当月最大天数)
124     public void setDayMax(){
125         int dayMax = this.mon_maxnum[this.getMonth().getValue()];
126     }
127     //DateUtil校验输入数据合法性
128     public boolean checkInputValidity(){
129         if (this.getYear().validate() && this.getMonth().validate()){
130             if(this.getDay().getValue() >= 1 && this.getDay().getValue() <= this.mon_maxnum[this.getMonth().getValue() - 1]){
131                 return true;
132             }else return false;
133         }else return false;
134     }
135     //求下n天
136     public DateUtil getNextNDays(int n){
137         //计算当前日期在一年里的第几天
138         int sum = 0,daysum = 0;
139         if (this.getMonth().getValue() - 1 == 0){
140             this.getMonth().monthReduction();
141         }
142         for(int i = 0; i < this.getMonth().getValue() - 1; i ++){
143             if(this.getYear().isLeapYear()){
144                 mon_maxnum[1] = 29;
145             }else mon_maxnum[1] = 28;
146             sum += mon_maxnum[i];
147         }
148         sum += this.getDay().getValue();
149         //计算下个日期的年份
150         sum += n;
151         if(this.getYear().isLeapYear()){
152             daysum = 366;
153         }else{
154             daysum = 365;
155         }
156         while (sum - daysum > 0){//daysum==0
157             if(this.getYear().isLeapYear()){
158                 daysum = 366;
159             }else{
160                 daysum = 365;
161             }
162             sum = sum - daysum;
163             this.getYear().yearIncrement();
164             this.getMonth().resetMin();
165         }
166         if(this.getYear().isLeapYear()){
167             mon_maxnum[1] = 29;
168         }else{
169             mon_maxnum[1] = 28;
170         }
171         //sum是月与日
172         if(sum>mon_maxnum[0]) {//计算月日
173             for (int i = 0; sum > mon_maxnum[i]; i++) {
174                 sum = sum - mon_maxnum[i];
175                 this.getMonth().setValue(i);
176             }
177             this.getMonth().monthIncrement();
178         }
179         this.getDay().setValue(sum);
180         this.getMonth().monthIncrement();
181         return this;
182     }
183     //求前n天
184     public DateUtil getPreviousNDays(int n){
185         //计算当前日期在一年里的第几天
186         int sum = 0,daysum = 0;
187         for(int i = 0; i < this.getMonth().getValue() - 1; i ++){
188             if(this.getYear().isLeapYear()){
189                 mon_maxnum[1] = 29;
190             }else mon_maxnum[1] = 28;
191             sum += mon_maxnum[i];
192         }
193         sum += this.getDay().getValue();
194         //计算下一个日期
195         sum -= n;
196         if(sum<0){//跨年了
197             if(this.getYear().isLeapYear(this.getYear().getValue()-1)){
198                 daysum = 366;
199             }else{
200                 daysum = 365;
201             }//计算年份
202             while (sum+daysum<0){
203                 if(this.getYear().isLeapYear(this.getYear().getValue()-1)){
204                     daysum = 366;
205                 }else{
206                     daysum = 365;
207                 }
208                 sum = sum+daysum;
209                 this.getYear().yearReduction();
210             }//计算正数的月份
211             this.getYear().setValue(this.getYear().getValue()-1);
212             if(this.getYear().isLeapYear()){
213                 daysum = 366;
214             }else{
215                 daysum = 365;
216             }
217             sum = daysum+sum;
218         }
219         if(this.getYear().isLeapYear()){
220             mon_maxnum[1] = 29;
221         }else{
222             mon_maxnum[1] = 28;
223         }
224         //计算月份
225         if(sum>mon_maxnum[0]) {//计算月日
226             for (int i = 0; sum > mon_maxnum[i]; i++) {
227                 sum = sum - mon_maxnum[i];
228                 //****
229                 this.getMonth().setValue(i);
230             }//****
231             this.getMonth().monthIncrement();
232         }
233         this.getDay().setValue(sum);
234         this.getMonth().monthIncrement();
235         return this;
236     }
237     //判定两个日期的先后
238     public boolean compareDates(DateUtil date){
239         if(this.getYear().getValue() - date.getYear().getValue() > 0){
240             return false;
241         }else if(this.getYear().getValue() - date.getYear().getValue() < 0){
242             return true;
243         }else if(this.getYear().getValue() - date.getYear().getValue() == 0){
244             if(this.getMonth().getValue() - date.getMonth().getValue() > 0){
245                 return false;
246             }else if(this.getMonth().getValue() - date.getMonth().getValue() < 0){
247                 return true;
248             }else if(this.getMonth().getValue() - date.getMonth().getValue() == 0){
249                 if(this.getDay().getValue() - date.getDay().getValue() > 0){
250                     return false;
251                 }else if(this.getDay().getValue() - date.getDay().getValue() < 0){
252                     return true;
253                 }
254             }
255         }
256         return true;
257     }
258     //判断两个日期是否相等
259     public boolean equalTwoDates(DateUtil date){
260         if(this.getYear().getValue() == date.getYear().getValue() && this.getMonth().getValue() == date.getMonth().getValue() && this.getDay().getValue() == date.getDay().getValue()){
261             return true;
262         }else return false;
263     }
264     //求两个日期的天数差
265     public int getDaysofDates(DateUtil date){
266         int n = 0;
267         if(equalTwoDates(date)){
268             return 0;
269         }else {
270             int k = 0;
271             //保证第一个日期始终在前
272             if (!compareDates(date)) {
273                 k = this.getYear().getValue();
274                 this.getYear().setValue(date.getYear().getValue());
275                 date.getYear().setValue(k);
276                 k = this.getMonth().getValue();
277                 this.getMonth().setValue(date.getMonth().getValue());
278                 date.getMonth().setValue(k);
279                 k = this.getDay().getValue();
280                 this.getDay().setValue(date.getDay().getValue());
281                 date.getDay().setValue(k);
282             }
283             //计算两个日期相差天数
284             //计算两个日期在一年里的位置
285             int sum1 = 0, daysum = 0, sum2 = 0;
286             for (int i = 0; i < this.getMonth().getValue() - 1; i ++) {
287                 if (this.getYear().isLeapYear()) {
288                     mon_maxnum[1] = 29;
289                 }
290                 else mon_maxnum[1] = 28;
291                 sum1 += mon_maxnum[i];
292             }
293             sum1 += this.getDay().getValue();
294 
295             for (int i = 0; i < date.getMonth().getValue() - 1; i ++) {
296                 if (date.getYear().isLeapYear()) {
297                     mon_maxnum[1] = 29;
298                 }
299                 else mon_maxnum[1] = 28;
300                 sum2 += mon_maxnum[i];
301             }
302             sum2 += date.getDay().getValue();
303             //计算两个日期相差的年份
304             for (; this.getYear().getValue() <= date.getYear().getValue() ;) {
305                 n += daysum;
306                 if (this.getYear().isLeapYear()) {
307                     daysum = 366;
308                 } else {
309                     daysum = 365;
310                 }
311                 this.getYear().yearIncrement();
312             }
313             n = n - sum1 +sum2;
314         }
315         return n;
316     }
317     //日期按年月日格式化
318     public String showDate(){
319         return (this.getYear().getValue() + "-" + this.getMonth().getValue() + "-" + this.getDay().getValue());
320     }
321 
322 }
323 class Year{
324     private int value;
325     public Year(){
326 
327     }
328     public Year(int value){
329         this.value = value;
330     }
331 
332     public int getValue() {
333         return value;
334     }
335 
336     public void setValue(int value) {
337         this.value = value;
338     }
339     //判断闰年
340     public boolean isLeapYear(){
341         return ((this.value % 400 ==0) || (this.value % 4 == 0 && this.value % 100 != 0));
342     }
343     public boolean isLeapYear(int year){
344         return ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0));
345     }
346     //year数据合法性校验
347     public boolean validate(){
348         if(this.value >= 1820 && this.value <= 2020){
349             return true;
350         }else return false;
351     }
352     //年增1
353     public void yearIncrement(){
354         this.value ++;
355     }
356     //年减1
357     public void yearReduction(){
358         this.value --;
359     }
360 }
361 class Month{
362     private int value;
363     public Month(){
364 
365     }
366     public Month(int value){
367         this.value = value;
368     }
369 
370     public int getValue() {
371         return value;
372     }
373 
374     public void setValue(int value) {
375         this.value = value;
376     }
377     //月份复位(1)
378     public void resetMin(){
379         this.value = 1;
380     }
381     //月份设置最大值(12)
382     public void reseMax(){
383         this.value = 12;
384     }
385     //month数据合法性校验
386     public boolean validate(){
387         if(this.value >= 1 && this.value <= 12){
388             return true;
389         }else return false;
390     }
391     //月增1
392     public void monthIncrement(){
393         this.value ++;
394     }
395     //月减1
396     public void monthReduction(){
397         this.value --;
398     }
399 }
400 class Day{
401     private int value;
402     public Day(){
403 
404     }
405     public Day(int value){
406         this.value = value;
407     }
408 
409     public int getValue() {
410         return value;
411     }
412 
413     public void setValue(int value) {
414         this.value = value;
415     }
416     //日增1
417     public void dayIncrement(){
418         this.value ++;
419     }
420     //日减1
421     public void dayReduction(){
422         this.value --;
423     }
424 }

它的PowerDesigner图像如下:

它的SourcePointer图像如下:

分析:这题与上一题用到的方法并没有什么不同,但是光从类图的结构的明显不同也可知它们绝不一样,7-5的类图是链式结构,7-6的类图是星形结构。在这一题中DateUtil类作为一个中心体与Day类,Month类,Year类直接接触,也就是说DateUtil类只要在类里面定义Day型day,Month型month,Year型year就可以直接利用day,month,year调用Day类,Month类,Year类里面的方法,调用方法与上一题的分析一致,例如在DateUtil类里面需要判断某年是不是闰年,就可以写day.isLeapYear()。将结构改为这样调用将变得格外简单,上一题想要调用判断是否为闰年这个方法足足要写好长一段,从DateUtil开始要调用Day,Month,Year每一个类,如果是一时还好,可是如果每一次想用方法都写一大长串叫人烦躁,代码的可读性也大大降低,写着写着使人眼花缭乱,容易出错。我私以为第二种聚合方法更加优秀。

从我自己的代码生成的类图分析:

不考虑聚合关系被关联取代的话,我的类图结果也没有什么问题。

从SourceMonitor来说也就是老调重弹了。暂时我对该怎么去改造还没什么想法。

题目集6的7-1

题目因为太长为了避免说是水字数就不放上了。

分析:我不能说自己为了这道题废寝忘食,但是我也不是什么都没写的。当我看到这题时,脑子非常混乱,因为经过几次迭代它变得无比复杂,光是比上一次迭代增加的异常情况就有17个。我只能尽量在那让人眼花缭乱的题目描述里找到这个题目的基本结构和基本思路。老师对我们还是放了水的,读了两遍题我大概知道自己要至少写5个类,一个Main类,一个Dish类,一个Menu类,一个Record类和一个Order类,Menu类和Order类分别包含Dish类和Record类,即Menu类和Dish类是组合关系,Order类和Record类是组合关系。一个Dish类是菜单上的一行信息,一个Record类是订单上的一行信息,根据Menu类里有addDish()方法,Order类里有addRecord()方法可知Menu类和Order类里面的Dish类数组和Record类数组应该是动态数组,不过这个想法是我现在想到的,还未进行验证,我的代码不是这样的,我之前想的是在addDiah()和addRecord()方法里面定义它进行操作的是一个动态数组,即在Menu类属性里面定义Dish是一个普通数组dishs,在addDiah()方法里面重新开辟了一个新空间给动态数组(ArrayList<Dish> dishs = new ArrayList<>()),两个数组的名字是一样的,我期待两者可以交互,但是这样和类本身的数组想来是根本不能进行联系的,想当然,不应该。

题目和时间是过不去了,鉴于订单要根据时间计算折扣和报错,我私以为应该加一个有关时间的类,一开始我定了一个名字DateUtil,后面改为了Date,这个和一次报错有关,我将放在下面的踩坑心得里面介绍。因为这个时间类不是老师给的,有关它的一切都要我自己摸索去设定,从上面介绍的两题我获取经验,我觉得它应该要有属性Day,Month,Year,根据题目还要加上Hour,Minute,Millisecond这三个属性,得要有判断时间是否正确的方法。一开始,我打算把判断数据格式合规和日期合法(时间在正常范围)两者写成一个方法,可是两者的输出是不一样的,放一起有违单一职责的设计原则,而且直接使用Java的自带判断时间是否合法的方法也比较麻烦,网上找到的代码都不能完全符合我的要求,混合对我的改写能力要求太高,再三考虑,我决定将它们分成两个方法。在时间类里还要有有一个方法用来判断时间是否在工作日,这是为了方便进行折扣的相关计算。我那时还暂时不打算考虑后续加餐的情况,于是就写了这几个类。代点餐我也没有考虑,一切都是为了能快速写出一些像样的东西来,可惜我没有得到好结果。现在再思考,时间类应该还要有判断后续桌号相同的点餐与上一次是否在一个小时内的方法,这是加餐了,得算在一个桌的费用里,命名为isSame就不错。

类差不多写完了,到Main类,显然Main类里面要有读取数据并且把它们分开的操作,写一个While循环,按行输入(读取),使用正则表达式,把每一行读到的数据按照人读的方式组成一个数组,在没读到菜单(菜单先)前的数据存入一个新的数组,或者说菜单和订单的每一行信息组成的数组非常特殊,需要存入Dish数组,Record数组,其他信息与它们分开储存。开始时我边读入数据边对它们进行处理(判断),但是报错是有顺序的,不可以即时报错,正确的顺序是先读完所有的数据,再对数据进行处理,再报错,这也是我不能把判断数据格式合规和日期合法(时间在正常范围)两者写成一个方法的原因之一,这两个方法只能是boolean类型,不能是void类型,方法绝不能有输出。那么Main类就要包括所有的输入和输出了。代点餐的判定我之前看了许久不能理解,现在好像可以理解了,输入框在一个小时内是专为一桌顾客服务的,如果加点菜的桌号保持相同,是本桌加餐,如果桌号是不同的,那就是代点餐。还得是输入数据的处理,只要输入的数据分好类,方法写对可行,剩下的事大概就剩各种判断。

 踩坑心得:一些题目我没有着重分析,是因为它们还不够难,但是我不是没有在写它们的时候犯错,比如题目集4的7-2有重复的数据,在嵌套循环判断两个数据是否相等的时候,首先我在判定相等后就立马输出NO,在循环结束后输出YES,结果是不论是否发现重复数据我都会输出YES,不符合题意。我那时想来有点昏头,想了许久,才想到使用一个判断常量。如下:

 1 for(int i = 0; i < n; i++){
 2             if(i!=0){
 3                 if(line[i]==line[i-1]){
 4                     flag=1;
 5                 }
 6             }
 7         }//循环结束后进行判断
 8         if(flag==1){
 9             System.out.print("YES");
10         }
11         if(flag==0){
12             System.out.print("NO");
13         }

如果找到重复数据就改变flag的值,以flag的值判定输出内容。

题目集5上来就给出4个正则表达式的题目作为拦路虎,此前我虽然在学习通上的课里学习了正则表达式,可是正则表达式的用法规则对新手的我来说多如牛毛,在这几题,好几次都是没能运用到正确的字符串分块方法导致结果有误,当然还有其他不熟的特殊字符的用法也使得我的攻题过程难以为继,比如说matches的用法,老师课上没讲,可它在题目里非常实用。matches查找一个字符串是否包含一个特定字符串,并且返回true或false,用在一些需要判断对错的题目里再合适不过。

大概这么用:

1 public static boolean isQualified (String s){
2              String regStr = "[1-9]\\d{4,14}";
3              return s.matches(regStr);
4         }

s是输入数据,regStr是要求的输入数据的基本格式。

写日期问题面向对象设计(聚合一)的时候,我看着类图不知道怎么下手,因为在这之前我没有写过在一个类里的属性是另一个类的题目(A类的属性里有B),我惶恐,战战兢兢按照基本步骤,在A类里给出B类的getter,setter方法,然后问题就来了,我该怎么去在A类里用B类的方法呢?也是运气,我在乱敲键盘的时候看见ijidea在我定义的B类对象加一点后(b.Bgetter())自动提示了B类的getter方法(B类的getter,setter方法已经写好),好新奇!我茅塞顿开。应用B类的方法得先用它的getter方法得到它。可是在A类方法里改变B对象的值的时候我又陷入难题,直接b.Bsetter() = *是错的!编译器不给过!那难道还能有别的方法不成?这时我连getter方法的用法都产生了怀疑。最终setter()的括号下的红线拉回了我离真相越来越远的脑洞,我把值(*)放进setter()的括号里(b.Bsettter(*)),果然对了。后面一切顺利。日期问题面向对象设计(聚合二)也是按照类图把一些表达一个一个修改就完成了。

到菜单计价程序-4,我想使用Java自带的判断时间是不是工作日的方法:

public boolean isWeekday(Date date) {
        //String[] weeks = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};

        Calendar cal = Calendar.getInstance();

        cal.setTime(date);

        int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;

        if(week_index<0){

            week_index = 0;

        }
        if (week_index == 1 || week_index == 7) {
            return false;
        } else {
            return true;
        }

但是传入数据Date类型一直报错,我以为是时间类名不相同(我的时间类叫DAteUtil),改后,编译还是报错。后知后觉,我发现Java是有独属于自己的Date类的,程序员可以重新自定义一个,但是传入的数据还是认自带Date类。无法,只有将(Date date )改为(java.util.Date date)。

Menu类里的Dish addDish()方法,我不知道该如何返回一个Dish类,苦思冥想,未果,翻找ArrayList相关内容,发现了.get()方法(return dishs.get(dishs.size()))。

改进建议:简单题目代码长度太短,都谈不上改进,难一点的题是日期类问题和菜单计价程序问题,前者的圈复杂度太大让人诟病,需要减少循环的数量,但是我不知道怎么做,后者我没写出来,谈不了改进。

总结:在这三个题目集里我更加熟悉了字符串的处理,尝试使用了正则表达式,试着运用了不用确定数组长度ArrayList数组,更加明白了类间关系聚合是怎么一回事。不过从菜单计价程序问题我很明白我根本不会用类里面的类数组与ArrayList的结合,我不会增加菜单或者订单。我也不会处理输入数据。字符串的处理应用从C语言开始就是我的心头大患。在这几个方面我还需要加强学习。对于作业这事我想提一点建议:希望老师在叫我们画类图后给出一个标准答案。不然真的会喜滋滋地以为就自己对了,其他人都错了。虽然说答案不唯一,可是老师的答案有助于我们在非常明显写错的时候改正。(和其他人讨论根本就谁也说服不了谁啊!)

标签:总结,题目,int,getValue,getYear,date,day,getMonth
From: https://www.cnblogs.com/wuyuxuansitong/p/17358849.html

相关文章

  • OOP 4-6次题目集总结
    前言:   通过前一个月的基础学习,对Java有了一定的了解,在这一个月中学习的知识难度明显增加,题目集的难度也随之增加。第四次的题目集主要考察对LinkedHashSet、ArrayList、Java的封装性、LocalDate类、String类、Integer类、Scanner类等的了解和简单使用。第五次的题目集主要考......
  • OOP训练集04-06总结(22201237-周琪)
    一、前言  在本次Blog必须分析题目集4的7-1、题目集5的7-5、7-6,题目集6的7-1,而这四道题目都是比较难的题目,除这四道题之外的题目,还会再总结几道踩坑较多、难度相对较低的题目。关于此次Blog需要总结的题目集的难度,总体来说还是比较大的,相较于之前的题目集,难度提升了很多,在之......
  • PTA题目集阶段总结(2)
    一、前言OOP训练集04:7题,第1题难度较大,第7题考查了较多的知识,也比较难;主要考察了Set、List和Java三大特性之一的封装性,并教我们学着查询JavaAPI文档,了解Scanner类、String类、Integer类、LocalDate类、ChronoUnit类中各种单位的用法和规则。OOP训练集05:6题,难度一般;主......
  • OOP题目集4-6总结
    前言:题目集4-6的题目量不大,但难度比较大,第4次题目集考察的知识点主要是字符串的使用以及数组;第5次题目集考察的知识点主要是正则表达式、类、字符串语法和数组语法的使用和聚合的使用;第6次题目集只有一道题目,但这道题目是由菜单计价程序叠加四次的题目,主要考察类和逻辑,测试点十分......
  • 哈希表总结
    哈希表总结常用数据结构总结数组有些时候,使用数组可以直接充当简单的哈希表,数组元素的下标作为key值,元素的值作为value值比如统计一个单词各个字符出现的次数,因为字母26个数目是有限的,所以数组的下标也是有限的,可以轻松实现。使用数组的情况,数组的下标一般都是有......
  • OOP题目集4~6总结
    前言:这次的题目集难度较以往而言提升了很多,突然提升的难度难免会造成些许的不适应。但是题目虽然有难度,同样的收获也与难度成正比增长。而这次题目集总结主要以三道大题来进行分析。  第四次作业:题目7-1菜单计价程序-3:需求分析:设计菜单点单计价程序,根据输入......
  • 南昌航空大学4-6次PTA总结
    对近期所学进行一个小结,主要针对pta上所发布的近三次作业,从多方面来分析这三次作业之间的联系和差异性,并从中了解自己的不足和缺点。最近的三次作业, 第一次作业除了第一题菜单类比较难其他还是比较简单,通过调用java自带的方法来节省我们编程的时间,主要考察的是我们对java的字符......
  • 最短路+二分题目整理
    前往奥格瑞玛的道路题目链接\(\qquad\)题目要求最小化最大费用,显然是使用二分答案,二分答案首先应该看限制和目标,此处的限制是血量限制,而目标是费用目标。这种情况我们可以二分费用,然后在图上跑最短路判定血量是否满足。\(\qquad\)对于check函数,我们去判定是否存在一条道路使得......
  • 刷题总结
    结束本轮的刷题任务感受颇多基本体现在双指针回溯以及动规上使用双指针法,定义两个指针(也可以说是索引下标),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。,时间复杂度是O(n)回溯算法能解决如下问题:组合问题:N个数里面按一定规则找出k个数的集合排列问......
  • 总结,从 766 开始(Div2 30)
    3.10A分块B 分数规划,以前没学过C推式子 3.11A推结论,先划分连续段,然后从一个长度>=k的连续段开始操作B推式子C平衡树套线段树(为了节省空间需要把内层线段树改成平衡树)或定期重构+树上差分+动态开点线段树,每个结点上有一棵线段树,每B次操作后向上合并 3.12......