JAVA面向对象程序设计_PTA题目集01-03总结分析

发布时间 2023-03-26 21:59:47作者: 耗子吃狗

前言:

JAVA_BLOG_PTA题目集1-3_总结分析

  题目集一

  知识点:主要覆盖了JAVA基本语法,例如数据类型、字符、数组等基础知识。

  题量:题量较大。

  难度:以五颗星为基准,难度大约在两颗,基础知识中与C具有一定程度的重叠和交互,学习难度不大,算法难度偏容易,但由于新接触JAVA,仍存在一定难度,做题过程具有一定挑战性,我的问题,我改。

  题目集二

       知识点:主要为数据处理与判断条件、循环条件的运用。

       题量:题量适当。

       难度:前几题主要涉及数据处理与条件判断,知识运用单一,且算法简单,难度较小。最后一题具有一定难度,算法相对于题目集三的三四题,是基础,但只做了这题时还是感受到了难度。

  题目集三

       知识点:相当于之前的题目,新涉及了private类型的运用和类的运用。

       题量:较小。

       难度:总难度约为前两次题目集总和的十分之七,(稍微看了眼题目集四好家伙难度搞数列啊An=An-1!*0.7这是),其中最后一题算法基于考虑内存与时限的前提,需要精简与调整,求前后N天的算法较为相似,但求差n天的算法,我的问题,我没做出来。我错了,我会改。难度对我来说较大,对别人,另说。

设计与分析

  03-7-3:

  源码数据:

  类图:

 

  源码:

 

 1 import java.util.*;
 2 
 3 public class Main{
 4     public static void main(String[] args){
 5         Scanner in = new Scanner(System.in);
 6         Date date = new Date();
 7         
 8         int year = in.nextInt();
 9         date.setYear(year);
10         int month = in.nextInt();
11         date.setMonth(year);
12         int day = in.nextInt();
13         date.setDay(day);
14         
15         if(date.checkInputValidity(year, month, day) == false){
16             System.out.println("Date Format is Wrong");
17         }
18         else if(date.checkInputValidity(year, month, day) == true){
19             date.getNextDate(year, month, day);
20         }
21     }
22 }
23 class Date{
24     private int year ;
25     private int month ;
26     private int day ;
27     
28     public Date(){
29     }
30     public void Date(int year, int month, int day){
31         this.year = year;
32         this.month = month;
33         this.day = day;
34     }
35     public void setYear(int year){
36         this.year = year;
37     }
38     public int getYear(){
39         return this.year;
40     }
41     public void setMonth(int month){
42         this.month = month;
43     }
44     public int getMonth(){
45         return this.year;
46     }
47     public void setDay(int day){
48         this.day = day;
49     }
50     public int getDay(){
51         return this.day;
52     }
53     public boolean isLeapYear(int year){
54         boolean result = false;
55         if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)){
56             result = true;
57         }
58         return result;
59     }
60     public boolean checkInputValidity(int year, int month, int day){
61         boolean result = true;
62         int []mon_maxnum = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
63         if(isLeapYear(year) == true){
64             mon_maxnum[2]++;
65         }
66         if(year < 1900 || year > 2000 || month < 1 ||
67             month > 12 || day < 1 || day > mon_maxnum[month]){
68             result = false;
69         }
70         return result;
71     }
72     public void getNextDate(int year, int month, int day){
73         
74         int []mon_maxnum = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
75         if(isLeapYear(year) == true){
76             mon_maxnum[2]++;
77         }
78         if(day > mon_maxnum[month]-1){
79             if(month < 12){
80                 month++;
81             }
82             else{
83                 year++;
84                 month = 1;
85             }
86             day = 1;
87         }
88         else{
89             day++;
90         }
91         System.out.printf("Next day is:%d-%d-%d", year, month, day);
92     }
93 }

 

  分析:

  02-7-9的算法迭代题。做过02-7-9听过老师的话问过同学,写起来轻松很多。设计其实简单,毕竟只有一个功能要求。不要判断变量,箴言。类图涉及的数据,我的粗浅理解只能看出来字面意思,这题确实是比较简单。这题类图是题目里直接给了的,做题过程中对我帮助很大,画类图是一个好习惯……

 

  03-7-4:

  源码数据:

 

  类图:

 

 

 

  源码:

 

  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.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");
 33             System.out.println(date.getNextNDays(m).showDate());
 34         } else if (choice == 2) { // test getPreviousNDays method
 35             int n = 0;
 36             year = Integer.parseInt(input.next());
 37             month = Integer.parseInt(input.next());
 38             day = Integer.parseInt(input.next());
 39 
 40             DateUtil date = new DateUtil(year, month, day);
 41 
 42             if (!date.checkInputValidity()) {
 43                 System.out.println("Wrong Format");
 44                 System.exit(0);
 45             }
 46 
 47             n = input.nextInt();
 48 
 49             if (n < 0) {
 50                 System.out.println("Wrong Format");
 51                 System.exit(0);
 52             }
 53 
 54             System.out.print(
 55                     date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:");
 56             System.out.println(date.getPreviousNDays(n).showDate());
 57         } else if (choice == 3) {    //test getDaysofDates method
 58             year = Integer.parseInt(input.next());
 59             month = Integer.parseInt(input.next());
 60             day = Integer.parseInt(input.next());
 61 
 62             int anotherYear = Integer.parseInt(input.next());
 63             int anotherMonth = Integer.parseInt(input.next());
 64             int anotherDay = Integer.parseInt(input.next());
 65 
 66             DateUtil fromDate = new DateUtil(year, month, day);
 67             DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
 68 
 69             if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
 70                 System.out.println("The days between " + fromDate.showDate() + 
 71                         " and " + toDate.showDate() + " are:"
 72                         + fromDate.getDaysofDates(toDate));
 73             } else {
 74                 System.out.println("Wrong Format");
 75                 System.exit(0);
 76             }
 77         }
 78         else{
 79             System.out.println("Wrong Format");
 80             System.exit(0);
 81         }        
 82     }
 83 }
 84 
 85 class DateUtil{
 86     private int year = 0;
 87     private int month = 0;
 88     private int day = 0;
 89     
 90     DateUtil(int year, int month, int day){
 91         this.year = year;
 92         this.month = month;
 93         this.day = day;
 94     }
 95     public void setYear(int year){
 96         this.year = year;
 97     }
 98     public int getYear(){
 99         return this.year;
100     }
101     public void setMonth(int month){
102         this.month = month;
103     }
104     public int getMonth(){
105         return this.month;
106     }
107     public void setDay(int day){
108         this.day = day;
109     }
110     public int getDay(){
111         return this.day;
112     }
113     //判断year是否为闰年
114     public boolean isLeapYear(int year){
115         boolean result = false;
116         if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)){
117             result = true;
118         }
119         return result;
120     }
121     //检测输入的年、月、日是否合法
122     public boolean checkInputValidity(){
123         boolean result = true;
124         int []mon_maxnum = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
125         if(isLeapYear(year) == true){
126             mon_maxnum[2]++;
127         }
128         if(year < 1820 || year > 2020 || month < 1 ||
129             month > 12 || day < 1 || day > mon_maxnum[month]){
130             result = false;
131         }
132         return result;
133     }
134         
135     //取得year-month-day的下n天日期
136     public DateUtil getNextNDays(int n){
137         int newyear = this.year;
138         int newmonth = this.month;
139         int newday = this.day;
140         int []mon_maxnum = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
141         for( ; n > 0; n--){
142             
143             if(isLeapYear(newyear) == true){
144                 mon_maxnum[2] = 29;
145             }
146             else{
147                 mon_maxnum[2] = 28;
148             }
149             if(newday > mon_maxnum[newmonth]-1){
150                 if(newmonth < 12){
151                     newmonth++;
152                     newday = 1;
153                 }
154                 else{
155                     newyear++;
156                     newmonth = 1;
157                     newday = 1;
158                 }
159             }
160             else{
161                 newday++;
162             }
163         }
164         return new DateUtil(newyear, newmonth, newday);
165 }
166     //取得year-month-day的前n天日期
167     public DateUtil getPreviousNDays(int n){
168         int newyear = this.year;
169         int newmonth = this.month;
170         int newday = this.day;
171         int []mon_maxnum = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
172         for( ; n>0; n--){
173             
174             if(isLeapYear(newyear) == true){
175                 mon_maxnum[2] = 29;
176             }
177             else{
178                 mon_maxnum[2] = 28;
179             }
180             if(newday > 1){
181                 newday--;
182             }
183             else{
184                 if(newmonth == 1){
185                     newyear--;
186                     newmonth = 12;
187                     newday = 31;
188                 }
189                 else{
190                     newmonth--;
191                     newday = mon_maxnum[newmonth];
192                 }
193             }
194         }
195         return new DateUtil(newyear, newmonth, newday);
196     }
197     //比较当前日期与date的大小(先后)
198     public boolean compareDates(DateUtil date){
199         boolean result = false;//
200         
201         if(date.year > this.year){
202             result = true;
203         }
204         else if(date.year == this.year){
205             if(date.month > this.month){
206                 result = true;
207             }
208             else if(date.month == this.month){
209                 if(date.day > this.day){
210                     result = true;
211                 }
212             }
213         }
214         return result;
215     }
216     //判断两个日期是否相等
217     public boolean equalTwoDates(DateUtil date){
218         boolean result = false;
219         
220         if(date.year == this.year && date.month == this.month && date.day == this.day){
221             result = true;
222         }
223         return result;
224     }
225 //求当前日期与date之间相差的天数
226     public int getDaysofDates(DateUtil date){
227         
228         int days = 0;
229         int []mon_maxnum = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
230         if(equalTwoDates(date) == true){
231             return days;
232         }
233         else {
234             if(this.year > date.year){
235                     //第一个日期年剩多少天
236                 
237                 if(isLeapYear(date.year)){
238                     mon_maxnum[2]++;
239                 }
240                 //头日期月剩余天数
241                 days = days + mon_maxnum[date.month] - date.day;
242                 //头日期年满月天数
243                 for(int i = (date.month+1); i <= 12; i++){
244                     days = days + mon_maxnum[i];
245                 }
246                 //中间年,year++,闰366
247                 for(int i = (date.year+1); i<this.year; i++){
248                     if(isLeapYear(i)){
249                         days = days + 366;
250                     }
251                     else{
252                         days = days + 365;
253                     }
254                 }
255                 //第二个日期多少天
256                 for(int i = 1; i<this.month; i++){
257                     if(isLeapYear(this.month)){
258                         mon_maxnum[2]++;
259                     }
260                     days = days + mon_maxnum[i];
261                 }
262                 days = days + this.day;
263                 }
264             else if(this.year == date.year){
265                 //头日期月剩余天数
266                 days = days + mon_maxnum[date.month] - date.day;
267                 //头日期年满月天数
268                 for(int i = (date.month+1); i <= (this.month-1); i++){
269                     days = days + mon_maxnum[i];
270                 }
271                 days = days + this.day;
272             }
273          }
274             
275         return days;
276     }
277     
278     //以“year-month-day”格式返回日期值
279     public String showDate(){
280         String str = String.valueOf(this.year + "-" + this.month + "-" + this.day);
281         return str;
282     }
283 }

 

  分析:

        03-7-3的超级加倍。设计是老师提醒。下n天是n个下一天,循环。前n天是下-n天。差值,查到的方法一,是拆分为三段,今年剩余天数、间隔年天数、第二个日期年天数。其中涉及同年不同月或同年同月等多种情况,我未能落实。查到的方法二,化用求下n天的方法,直接循环n++计算天数,运行报错超时和非零返回,不适用。语法里涉及的this.和date.是我的知识盲区,一开始写的时候完全没考虑到直接完大蛋,后面查到才知道要这样写,才活过来。多查查资料真的很有必要……

踩坑心得

       题目集一

       总结:一开始打算先看一下书再开始做题,抱着书读读读——好ddl直接逼近,好多不知道但是硬着头皮开始做,不会了不知道了再去查再去问,效果比自己干读书好得多……

       心得:编程,主打一个勇敢应用,边做边学才是正确方法,而非理论化操作。老师一句话讲的,你是司机不是汽车制造商。

       题目集二

       总结:难度不很大,但我够蠢。7-1和7-3数据类型问题,7-3计算问题,7-4选择判断,7-5奇数情况,7-6改了一堆后结果是输出问题,7-7的标志-1拆分,7-8数据精度和==与!=不能连用,7-9判断和算法。好在我初学好在我年轻,不然这些错误,我会在编程界自我绞杀。

       心得:问题总会解决,愚蠢可以改善。查询资料研究算法,目前遇到的问题都可以解决,尤其,报错集很需要收集整理和反复查看,发现在实验一遇见的问题存在于我的报错集里的我如是说。

  另:做题过程中稍微记录了点思路,在这里贴点图,权当自我警醒。

  02-7-6

 

  02-7-7

 1 import java.util.*;
 2 
 3 public class Main{
 4     public static void main(String[] args){
 5         
 6         Scanner in = new Scanner(System.in);
 7         //order序列
 8         String order = in.nextLine();
 9         String printOrder = "";
10         
11         for(int i=0; i<order.length(); i++){
12             if( order.charAt(i)=='1' || order.charAt(i)== '0'){
13                 printOrder = printOrder+order.charAt(i);
14             }
15             //charAt()用不来i=j,换方法
16             //没说非法输入也要做
17             else if(order.charAt(i)=='-'){
18                 if(order.charAt(i+1)=='1'){
19                     System.out.print(printOrder);
20                     return;
21                 }
22                 
23             }
24         }
25         //Wrong:跑完循环没输出即非法
26         //非法:没有-1,——》拆开-1,
27         //???return?break?
28         System.out.print("Wrong Format");
29     }
30 }

  分析:

  这题结束标志是-1调了半天没调出来,因为我把-1当整体去调了。但是其实原题的提示是明显的,字符串,-和1,各一个字符啊(点赛博烟。真就是题做少了,没有敏锐度——

  另外,这题,还有类似的涉及字符串里处理个别字符的题,我用套循环在原字符串进行修改的方法都会报错非零返回,查了发现非零返回大概是数组溢出的意思,但是一个字符串的长度扩展我只想得到放进一个新的更大的数组里再处理的方法,这样做又过于繁琐,且所有问题都套循环,好蠢。所以学了新方法......

 

 

   02-7-8

 

 

       题目集三

       总结:

  这是我第一次写private数据和类,写得非常混乱和艰难,bug比我头发还多,报错把所有错都报过。写完之后发现其实运用没那么难(至少这四题都是能接受的程度,别的题我无法评价),参考的例子都比较简单或者过于复杂,看了用不来或者看了看不懂。后面做下来再回去看,很多东西其实就是用过之后才知道是怎么回事。写7-4的前几天,n大于700数据就乱了,后面的修改是把漏了的判断非闰月二月28天加回去。我改这块运算改了好久结果是判断的问题,从这点学到的,题目出的错误结果是有可能看不出代码错在哪的,多读读代码自己到处优化到处改改多试试。

  心得:

  测边界值和IDEA真的很好用,是事后诸葛亮,写作业的时候居然没想到用IDEA……好用,多用。算法除了7-4都相对简单。学的知识简单,知识的运用也基础。这个阶段对我的指导更多在于认清自己未来作业就业方向和道路,思想教育成果有。

  写代码必然会有改bug的过程,既然什么都不会,那就什么都试试,自己搞不定就问别人,现在能遇见的Java问题,没有解决不了的。笨方法也是方法,但是要从笨方法精简成好方法。多读读代码自己到处优化到处改改多试试,答案错误不一定是直接的运算错误,到处多改改。

  另:

  03-7-2:

  源码:

  1 import java.util.*;
  2 import java.time.LocalDate;
  3 
  4 public class Main{
  5     public static void main(String[] args){
  6         
  7         Scanner in = new Scanner(System.in);
  8         Account account = new Account();//创建一个账户
  9         
 10         //数据
 11         int id = in.nextInt();
 12         account.setId(id);
 13         double balance = in.nextDouble();
 14         account.setBalance(balance) ;
 15         double annualInterestRate = in.nextDouble();
 16         account.setAnnualInterestRate(annualInterestRate);
 17         double withdraw = in.nextDouble();
 18         double money = in.nextDouble();
 19         double newbalance = 0.0;
 20         
 21         
 22         //取,存错误
 23         if(account.withDraw(withdraw) == false || account.deposit(money) == false){
 24             newbalance = balance;
 25             
 26             if(account.withDraw(withdraw) == true){
 27                 newbalance = balance - withdraw;
 28             }
 29             else 
 30                 System.out.println("WithDraw Amount Wrong");
 31                 
 32             if(account.deposit(money) == true){
 33                 newbalance = balance + money;
 34             }
 35             else
 36                 System.out.println("Deposit Amount Wrong");
 37             
 38                 System.out.printf("The Account'balance:%.2f\n",newbalance);
 39                 System.out.printf("The Monthly interest:%.2f\n",
 40                                   (account.getMonthlyInterestRate(newbalance, account.getAnnualInterestRate())));
 41                 account.getDateCreated();
 42         }
 43         if(account.withDraw(withdraw) == true && account.deposit(money) == true){
 44             newbalance = balance - withdraw + money;
 45             System.out.printf("The Account'balance:%.2f\n",newbalance);
 46             System.out.printf("The Monthly interest:%.2f\n",
 47                               (account.getMonthlyInterestRate(newbalance, account.getAnnualInterestRate())));
 48             account.getDateCreated();
 49         }
 50         
 51         
 52     }
 53 }
 54 class Account{
 55     private int id = 0;
 56     private double balance = 0.0;
 57     private double annualInterestRate = 0.0;
 58     private LocalDate dateCreated;//默认日期200731
 59     
 60     public Account(){
 61     }
 62     //setter
 63     public void setId(int id){
 64         this.id = id;
 65     }
 66     public void setBalance(double balance){
 67         this.balance = balance;
 68     }
 69     public void setAnnualInterestRate(double annualInterestRate){
 70         this.annualInterestRate = annualInterestRate;
 71     }
 72     //getter
 73     public int getId(){
 74         return this.id;
 75     }
 76     public double getBalance(){
 77         return this.balance;
 78     }
 79     public double getAnnualInterestRate(){
 80         return this.annualInterestRate;
 81     }
 82     public void getDateCreated(){
 83         //LocalDate型getter用void
 84         System.out.print("The Account'dateCreated:2020-07-31");
 85     }
 86     //月利率
 87     public double getMonthlyInterestRate(double balance, double annualInterestRate){
 88         double MonthlyInterestRate;
 89         MonthlyInterestRate = balance * (annualInterestRate/1200.0);
 90         return MonthlyInterestRate;
 91     }
 92     //提取数额
 93     public boolean withDraw(double withdraw){
 94         boolean result = true;
 95         if(withdraw > balance || withdraw < 0){
 96             result = false;
 97         }
 98         return result;
 99     }
100     //存储数额
101     public boolean deposit(double money){
102         boolean result = true;
103         if(money > 20000 || money < 0){
104             result = false;
105         }
106         return result;
107     }
108     public void Account(int id, double balance, double annualInterestRate){
109         this.id = id;
110         this.balance = balance;
111         this.annualInterestRate = annualInterestRate;
112     }
113 }

  分析:

  这段代码真的很能体现当事人清澈的愚蠢(点赛博烟。

  一开始是类的构建和数据的设置有误,再是没有在主方法new新账户,接着是运算问题。默认日期一开始没反应过来还去调了个库(二次赛伯烟。细节问题很多,考虑不完善,遇见问题查了资料没仔细研究自己吃透就生搬硬套。用老师的话,非常不专业,怎么不专业怎么来。由此浪费了很多时间——我改。

  

 

 

 

 

 

 

  

  

 

对自己的改进建议

    (注:部分题目编码较为简单,笔者才疏学浅无法改进,不作建议。且适用于所有题目的改进建议另作记录,不在各题重复记录。)

       总:

   将代码格式完全规范,思路为方便写在末尾,别中途突然插两句;

              在设置时统一初始化所有数据,以免除后续数据初始化报错;

              输出函数的选择:02-7-6;

              数据精度:02-7-8;

         对于查找到的函数用法进行研究理解后再使用,而非生搬硬套。可以边用边调试边理解,切忌主打一个勇敢什么都不懂乱七八糟套。问题题目:02-7-5;

         返回值不用另设,直接返回:03-7-1,03-7-2,03-7-4;

       题目集二:

              7-4:选择结构过于累赘,可以改switchcase或者if(m关系n);

         7-9:老师说的,(害写这个blog发现真是老师说的都具有很高的实际操作意义和参考价值),不要判断变量。应该把月份数组以下,去判断数组的。这版写得又臭又长还过不了最后一个测试点,啧。

       题目集三:

              7-2:set和get按变量区分,而非按setter和getter区分;

                      多写注释,看得脑壳疼;

              7-4:操作重复,三个判断里涉及同一操作,提出来放外面;

                      相差n天的算法,写不来,我的错,会改进,会研究,会进步。

总结

       学到了什么:

  1.听起来很水但是,真的有所谓的磨练意志、平衡心态和学习态度。直接体现,我现在能做到看眼通知立刻接受题目集四了。印象深刻且非常赞同的老师讲的,学不完压力大,原因,时间不够,效率不行,方法不对。说的是我,我接受,我改。

  2.专业知识。类的基本设计,私有属性的使用,方法的使用,以及前文提到过的纠错知识。基本函数的使用,以及如何学习使用函数Java库里自带的函数,利用idea进行调试与修改,SourceMonitor和PowerDesigner的基础使用,以及利用其生成的报表与类图进行分析。

       进一步学习及研究的地方:

  1.基础知识。要熟读Java教材,很多做题过程中遇见的问题和知识点其中都有提及;

       2.public,private的更详细的用法与知识。做题时只学了需要的皮毛;

       3.IDEA、SoureMonitor、PoweiDesigner,很多功能还不会用,但因为其功能过于强大,还是按需学习使用。

       4.优化算法。笔者做题思路局限且单一,还是多看多学。早日消灭我清澈的愚蠢;

       5.这次blog是事后写的,很多错误或者当时的思路都没有记录下来。下次得边写代码边记录……嗯第四次题目集已经开了。

       教师、课程、作业、实验、课上课下组织方式:

  1.基本无,现在还处在把自己塞进去这套教学方法的阶段没觉得哪里不合适。改变规则首先得掌握规则。但是如果可以小小提一下,换个教室吗长长一条抢不到前排的时候……看板书有一种朦胧美。

  另:

  感谢我的室友们和朋友们在编程学习方面对我的帮助,这对我而言意义重大。

  也谢谢老师,你教得是好的。

  辛苦阅读,耗子吃狗祝您生活愉快。