题目4-6的总结
一.前言
题目集4-6的知识点主要考察了正则表达式和对复杂字符串的处理,继承多态接口等。题目集4,5的题量较少,难度中等。而题目集6的题量较多但好在简单不麻烦。
二.设计与分析
①题目集4(7-2)、题目集5(7-5)两种日期类聚合这几的优劣比较
下面分析一下题目集4(7-2)和题目集5(7-5)的聚合方式
题目集4(7-2)

聚合是整体和部分的关系,这里是把Day当成DateUtil的一部分,把Month当成Day的一部分,把Year当成Month的一部分.主函数中只要调用DateUtil的带参构造方法。在DateUtil的带参构造方法中调用Day的带参构造方法。在Day的带参构造方法中调用Month的带参构造方法。在Month的带参构造方法中调用Year的带参构造方法。
下面是它的source monitor分析

在写代码的过程中这种思路不难理解,但比较容易出错。因为在DateUtil不断去调用this.day里的month,在从month调用year,不留神就会容易出错。
题目集5(7-5)

由类图可以知道Year,Month,Day是DateUtil的一部分,很容易理解,因为日期由年月日组成。
下面是它的source monitor分析

下面是两个聚合方式的比较

第一个为聚合方式二,第二个是聚合方式一。可以看出除了函数、方法的数量高一点,其它的数值都比聚合方式二小。从类图上来看,每个类的功能方法没有什么区别,唯一的区别就是它们的聚合方式不同,从数据来看,选择聚合方式一会比较好一点,写法上需要仔细一点。
②题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)
题目集4(7-3)


本题是子类Circle和Rectangle继承父类Shape,子类Box和Ball分别继承父类的Rectangle和Circle。Circle和Rectangle重写父类Shape的getArea()方法,并且有自己的其他方法。子类Box继承父类Rectangle,重写了父类的show、getArea、getVolume、judge方法。这里写博客的时候发现了一个问题,就是Box类中少了width和length的属性。程序能够运行起来且过了测试点是因为传了参数给getVolume和getArea方法,故没出错。子类Ball继承父类Circle,重写了父类的show、getArea、getVolume的方法。由于Ball的属性也是只有一个circle,所以它的judge只要继承父类的Circle的judge方法即可。
题目集6(7-5)


本题是子类Triangle、Circle和Rectangle继承父类Shape,而子类分别都改写了父类的getArea和validata的方法。另外新增了一个类进行了数组的排序和求和。
题目集6(7-6)


本题是创造接口GetArea,Rectangle、Circle重写接口的getArea()的方法。
创造了一个抽象类GetArea,其中有一个getArea()方法的抽象,并没有实体。而在Rectangle和Circle中可以将这个抽象的方法具体。
③对三次题目集中用到的正则表达式技术的分析总结
在三次题目集中,前两次的题目集个出现了一题,分别是水文校验,关键字判断。最后一次出现四个关于正则表达式的题目,但题目比较单一和简单。主要复杂的还是水温校验和关键字的判断。
关于正则表达式,我认为正则表达式不仅仅只是一些字符串起来匹配字符,更重要的是怎么去处理你输入的字符。大家都知道关于正则表达式很难,而输入字符串的处理正是简化了你创造正则表达式的工作量。在这三次pta中我们常用 StringBuilder.apends去拼接字符串,String.Split去切割字符串,String.repalce去替换字符串中某些我们不想要出现的字符。
对题目集4(7-1)来说,题目要求对每行输入的一条数据,而一条数据中又有着4、5列,对其进行合法性校验及计算。思路是这样的:由于每一行数据都要进行校验,以exit为结束字符串。想办法将每一行数据都放在一个数组中,再在数组中遍历将每一条数据切割为我们要判断的数据。在输入的循环中用StringBuilder.apend(\n).apend(输入的每一行字符串),输入完成后在用split分割放入字符串数组中。在遍历数组中,还是用split函数按照题目所给的格式,将数据项分给出来存至变量中,等待校验。
下面是关于水文校验的正则表达式。开始对正则表达式还是不是特别熟悉,看了关于上次多项式求导的正则表示一堆符号表示眼花缭乱。这次认真去看了网上一个人的关于基础的正则表达式,初步的理解是将所有可能的情况一个一个列出来。不过这道题目的情况不多就是比较麻烦,如果题目要求的情况更多的时候,这个时候就不能把这么多的情况写出来了,要用到贪心匹配。所以这道题目写正则表达式还是花了我大量时间的去写它的正则表达式
1 import java.time.LocalDateTime; 2 import java.util.Scanner; 3 public class Main { 4 5 public static void main(String[] args) { 6 // TODO 自动生成的方法存根 7 Scanner in=new Scanner(System.in); 8 StringBuilder str=new StringBuilder(in.nextLine()); 9 String exit="exit"; 10 String a=in.nextLine(); 11 while(!a.equals(exit)) 12 { 13 str.append('\n').append(a); 14 a=in.nextLine();//输入数据给a 15 } 16 String S= String.valueOf(str); 17 String M[]=S.split("\n"); 18 HydrologicalInfo[] Info=new HydrologicalInfo[M.length]; 19 int[] flag=new int[M.length]; 20 int xflag=0; 21 int x=0; 22 for(int i=0;i<M.length;i++) 23 { 24 Info[i]=new HydrologicalInfo(); 25 26 } 27 for(int i=0;i<M.length;i++) 28 { 29 CheckData check=new CheckData(M[i],i+1); 30 String num[]=M[i].split("\\|"); //把数据分为五部分,分别是测量时间,目标水位,实际水位,开度(目标开度/实际开度),流量 31 if(num.length<5) 32 { System.out.println("Wrong Format"); 33 System.out.println("Data:"+M[i]); 34 flag[i]=1; 35 x=1; 36 } 37 else 38 { 39 40 String timer=num[0].trim(); 41 String targetlevel=num[1].trim(); 42 String realitylevel=num[2].trim(); 43 String rate=num[4].trim(); 44 String gateopen=num[3].trim(); 45 String OP[]=num[3].split("\\/"); 46 String tgateopen=OP[0]; 47 String agateopen=OP[1]; 48 StringBuilder n=new StringBuilder(); 49 //2015/8/2 4:00|133.8400|133.070|1.11/1.21|75.780 50 n.append(timer).append("|").append(targetlevel).append("|").append(realitylevel).append("|").append(gateopen).append("|").append(rate); 51 if(!check.validateMeasureDateTime(timer)) 52 { 53 //Row:行号,Column:列号Wrong Format 54 System.out.println("Row:"+(i+1)+",Column:1Wrong Format"); 55 flag[i]=1; 56 } 57 if(!check.validateWaterLevel(targetlevel)) 58 { 59 System.out.println("Row:"+(i+1)+",Column:2Wrong Format");flag[i]=1; 60 } 61 if(!check.validateWaterLevel(realitylevel)) 62 { 63 System.out.println("Row:"+(i+1)+",Column:3Wrong Format");flag[i]=1; 64 } 65 if(!check.validateGateOpening(gateopen)) 66 { 67 if(!OP[0].matches("([1-9])\\.([0-9][0-9])")) 68 System.out.println("Row:"+(i+1)+",Column:4Wrong Format");flag[i]=1; 69 if(!OP[1].matches("([1-9])\\.([0-9][0-9])")) 70 System.out.println("Row:"+(i+1)+",Column:5Wrong Format");flag[i]=1; 71 } 72 if(!check.validateWaterLevel(rate)) 73 { 74 System.out.println("Row:"+(i+1)+",Column:6Wrong Format");flag[i]=1; 75 } 76 if(flag[i]==1) 77 { 78 //if(i==M.length-1) 79 //System.out.print("Data:"+n);xflag=1; 80 System.out.println("Data:"+M[i]);xflag=1; 81 } 82 if(check.validateMeasureDateTime(timer)&&check.validateWaterLevel(targetlevel)&&check.validateWaterLevel(realitylevel) 83 &&check.validateGateOpening(gateopen)&&check.validateWaterLevel(rate)) 84 { 85 Info[i].setObjectWaterLevel(Double.parseDouble(targetlevel)); 86 Info[i].setActualWaterLevel(Double.parseDouble(realitylevel)); 87 Info[i].setObjectGateOpening(Double.parseDouble(tgateopen)); 88 Info[i].setActualGateOpening(Double.parseDouble(agateopen)); 89 Info[i].setWaterFlow(Double.parseDouble(rate)); 90 91 92 } 93 } 94 } 95 if(xflag!=1&&x!=1) 96 { 97 for(int i=0;i<M.length;i++) 98 { 99 String num[]=M[i].split("\\|"); //把数据分为五部分,分别是测量时间,目标水位,实际水位,开度(目标开度/实际开度),流量 100 String OP[]=num[3].split("\\/"); 101 if(OP[0].compareTo(OP[1])<0) 102 { 103 System.out.println("Row:"+(i+1)+" GateOpening Warning"); 104 } 105 } 106 DealData deal=new DealData(); 107 deal.computerData(Info,M.length); 108 } 109 } 110 111 } 112 113 114 class CheckData{ 115 String data; 116 int row; 117 CheckData() 118 {} 119 CheckData(String data,int row) 120 { 121 this.data=data; 122 this.row=row; 123 } 124 void setData(String data,int row) 125 { 126 this.data=data; 127 this.row=row; 128 } 129 String getData() 130 { 131 return this.data; 132 } 133 boolean validateData() 134 { 135 boolean flag=true; 136 return flag; 137 } 138 boolean validateMeasureDateTime(String measureDateTime) 139 { 140 boolean flag=true; 141 String timer="(([1-9])|([1-9]\\d)|([1-9]\\d{2})|([1-9]\\d{3}))" 142 +"/" 143 + "((([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])))" 144 + "\\s(((([02468])|(1[02468])|(2[024])):((00))))"; 145 if(!measureDateTime.matches(timer)) 146 flag=false; 147 return flag; 148 //(((([02468])|(1[02468])|(2[024])):((00))))"; 149 150 } 151 boolean validateWaterLevel(String waterLevel) 152 { 153 boolean flag=true; 154 //匹配目标水位,实际水位,流量 155 String part1="(([1-9])|([1-9]\\d)|([1-9]\\d{2}))" 156 + "|((([1-9])|([1-9]\\d)|([1-9]\\d{2}))\\.((000)|(00[1-9])|(0[1-9]\\d)|(0[1-9])|([1-9])|([1-9][1-9])|([1-9]\\d{2})))"; 157 if(!waterLevel.matches(part1)) 158 flag=false; 159 return flag; 160 } 161 boolean validateGateOpening(String gateOpening) 162 { 163 boolean flag=true; 164 //匹配开度 165 String part2="((([1-9])\\.([0-9][0-9]))/(([1-9])\\.([0-9][0-9])))"; 166 if(!gateOpening.matches(part2)) 167 flag=false; 168 return flag; 169 } 170 171 } 172 173 class DealData 174 { 175 StringBuilder sb; 176 DealData(){} 177 DealData(StringBuilder sb) 178 { 179 this.sb=sb; 180 } 181 StringBuilder getSb() 182 { 183 return this.sb; 184 } 185 void setSb(StringBuilder sb) 186 { 187 this.sb=sb; 188 } 189 void getDealDataResult() 190 { 191 192 } 193 void computerData(HydrologicalInfo hydrologicalInfo[],int num) 194 { 195 int i;double Max=0; 196 double total = 0; 197 for(i=0;i<num;i++) 198 { 199 if(hydrologicalInfo[i].actualWaterLevel>Max) 200 { 201 Max=hydrologicalInfo[i].actualWaterLevel; 202 } 203 total=total+2*60*60*hydrologicalInfo[i].waterFlow; 204 } 205 System.out.printf("Max Actual Water Level:%.2f\n",Max); 206 System.out.printf("Total Water Flow:%.2f",total); 207 } 208 } 209 class HydrologicalInfo{ 210 //LocalDateTime measureDateTime; 211 double objectWaterLevel;double actualWaterLevel;double objectGateOpening;double actualGateOpening;double waterFlow; 212 HydrologicalInfo(){} 213 HydrologicalInfo(double objectWaterLevel,double actualWaterLevel,double objectGateOpening,double actualGateOpening,double waterFlow) 214 { 215 this.actualGateOpening=actualGateOpening; 216 this.actualWaterLevel=actualWaterLevel; 217 this.objectGateOpening=actualGateOpening; 218 this.objectWaterLevel=objectWaterLevel; 219 this.waterFlow=waterFlow; 220 } 221 double getObjectWaterLevel() 222 { 223 return this.objectWaterLevel; 224 } 225 void setObjectWaterLevel(double objectWaterLevel) 226 { 227 this.objectWaterLevel=objectWaterLevel; 228 } 229 double getActualWaterLevel() 230 { 231 return this.actualWaterLevel; 232 } 233 void setActualWaterLevel(double ActualWaterLevel) 234 { 235 this.actualWaterLevel=ActualWaterLevel; 236 } 237 double getObjectGateOpening() 238 { 239 return this.objectGateOpening; 240 } 241 void setObjectGateOpening(double objectGateOpening) 242 { 243 this.objectGateOpening=objectGateOpening; 244 } 245 double getActualGateOpening() 246 { 247 return this.actualGateOpening; 248 } 249 250 void setActualGateOpening(double actualGateOpening) 251 { 252 this.actualGateOpening=actualGateOpening; 253 } 254 double getWaterFlow() 255 { 256 return this.waterFlow; 257 } 258 void setWaterFlow(double WaterFlow) 259 { 260 this.waterFlow=WaterFlow; 261 } 262 }
④题目集5(7-4)中Java集合框架应用的分析总结
由于写题目的时候没有看到旁边的解题报告要求题目必须使用List、Set或Map中一种或多种,我是按普通的类去写的。去查找了一下资料,理解是:
集合只能保存对象,不能保存数据,并且每种集合有它自己规定的方法。
java集合框架是Java写好的一些管理数据的类库,主要分为两大部分,Map接口,collection接口
列举几种接口:
ArrrayList类:
1.处理有序的单列数据,可以有重复的数据。
2.添加的元素会自动扩展
3.动态数据结构,查询数据快,添加删除数据慢
LinkedList类:
1.处理有序的单列数据,可以有重复的数据。
2.添加数据会自动扩展
3.双向链表结构,查询数据慢,添加删除数据快。
Set接口时用来处理无序的单列数据,没有重复的元素,重复的元素算第一个。
HashSet类
1.处理无序的单列数据,没有重复的元素,重复的元素算第一个。
LinkedHashSet类
用来处理无序的单列数据,没有重复的元素,重复的元素算第一个
HashMap类
1.用来处理键值对数据的集合
2.允许有null键--null 值--null
Hashtable类
1.用来处理键值对数据的集合
2.不允许有null
如果在做题目中能很好的使用这些接口的话,能给我们省了不好事情。
三、踩坑心得
有个比较严重的坑就是在题目集5(7-4)这里统计Java关键词次数。下面展示部分代码:
while(!line.equals("exit"))
{
line.replaceAll("//.*", " ");//去除\\后面的注释(一定是一行一行去除)
line.replaceAll("\".*\"", " ");//去除双引号""内的内容(一定是一行一行去除)
source.append(line);
line=in.nextLine();x=1;
}
看上去是没有任何问题,没错呀,要去除//后面的注释,要去除""之内的内容,用replaceAll把这些替换成空格没有丝毫问题。但在我调试的时候,对于//和""要替换的内容并没有替换。
对于repalceAll:replaceAll()返回值replaceAll()方法返回一个新字符串,其中每次匹配子字符串的出现都替换为替换字符串(replacement)。所以这里是我把//和""替换后返回了我替换后的字符串,但我并没有把替换后的字符串赋给哪个变量,也就是在上述的使用replaceAll的代码中,实际上字符串line并没有改变。
修改后的代码:
while(!line.equals("exit")) { source.append(line.replaceAll("//.*", " ").replaceAll("\".*\"", " ")); line=in.nextLine();x=1; }
这样就成功把替换后的字符串接在了source的后面。
还有水文校验的题目,这个题目的描述太长,要求太多,但文字的描述读着读着总会有歧义导致,导致理解错了几个题目的要求,错误百出。
四、改进建议
import java.time.LocalDateTime; import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO 自动生成的方法存根 Scanner in=new Scanner(System.in); StringBuilder str=new StringBuilder(in.nextLine()); String exit="exit"; String a=in.nextLine(); while(!a.equals(exit)) { str.append('\n').append(a); a=in.nextLine();//输入数据给a } String S= String.valueOf(str); String M[]=S.split("\n"); HydrologicalInfo[] Info=new HydrologicalInfo[M.length]; int[] flag=new int[M.length]; int xflag=0; int x=0; for(int i=0;i<M.length;i++) { Info[i]=new HydrologicalInfo(); } for(int i=0;i<M.length;i++) { CheckData check=new CheckData(M[i],i+1); String num[]=M[i].split("\\|"); //把数据分为五部分,分别是测量时间,目标水位,实际水位,开度(目标开度/实际开度),流量 if(num.length<5) { System.out.println("Wrong Format"); System.out.println("Data:"+M[i]); flag[i]=1; x=1; } else { String timer=num[0].trim(); String targetlevel=num[1].trim(); String realitylevel=num[2].trim(); String rate=num[4].trim(); String gateopen=num[3].trim(); String OP[]=num[3].split("\\/"); String tgateopen=OP[0]; String agateopen=OP[1]; StringBuilder n=new StringBuilder(); //2015/8/2 4:00|133.8400|133.070|1.11/1.21|75.780 n.append(timer).append("|").append(targetlevel).append("|").append(realitylevel).append("|").append(gateopen).append("|").append(rate); if(!check.validateMeasureDateTime(timer)) { //Row:行号,Column:列号Wrong Format System.out.println("Row:"+(i+1)+",Column:1Wrong Format"); flag[i]=1; } if(!check.validateWaterLevel(targetlevel)) { System.out.println("Row:"+(i+1)+",Column:2Wrong Format");flag[i]=1; } if(!check.validateWaterLevel(realitylevel)) { System.out.println("Row:"+(i+1)+",Column:3Wrong Format");flag[i]=1; } if(!check.validateGateOpening(gateopen)) { if(!OP[0].matches("([1-9])\\.([0-9][0-9])")) System.out.println("Row:"+(i+1)+",Column:4Wrong Format");flag[i]=1; if(!OP[1].matches("([1-9])\\.([0-9][0-9])")) System.out.println("Row:"+(i+1)+",Column:5Wrong Format");flag[i]=1; } if(!check.validateWaterLevel(rate)) { System.out.println("Row:"+(i+1)+",Column:6Wrong Format");flag[i]=1; } if(flag[i]==1) { //if(i==M.length-1) //System.out.print("Data:"+n);xflag=1; System.out.println("Data:"+M[i]);xflag=1; } if(check.validateMeasureDateTime(timer)&&check.validateWaterLevel(targetlevel)&&check.validateWaterLevel(realitylevel) &&check.validateGateOpening(gateopen)&&check.validateWaterLevel(rate)) { Info[i].setObjectWaterLevel(Double.parseDouble(targetlevel)); Info[i].setActualWaterLevel(Double.parseDouble(realitylevel)); Info[i].setObjectGateOpening(Double.parseDouble(tgateopen)); Info[i].setActualGateOpening(Double.parseDouble(agateopen)); Info[i].setWaterFlow(Double.parseDouble(rate)); } } } if(xflag!=1&&x!=1) { for(int i=0;i<M.length;i++) { String num[]=M[i].split("\\|"); //把数据分为五部分,分别是测量时间,目标水位,实际水位,开度(目标开度/实际开度),流量 String OP[]=num[3].split("\\/"); if(OP[0].compareTo(OP[1])<0) { System.out.println("Row:"+(i+1)+" GateOpening Warning"); } } DealData deal=new DealData(); deal.computerData(Info,M.length); } } } class CheckData{ String data; int row; CheckData() {} CheckData(String data,int row) { this.data=data; this.row=row; } void setData(String data,int row) { this.data=data; this.row=row; } String getData() { return this.data; } boolean validateData() { boolean flag=true; return flag; } boolean validateMeasureDateTime(String measureDateTime) { boolean flag=true; String timer="(([1-9])|([1-9]\\d)|([1-9]\\d{2})|([1-9]\\d{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])))" + "\\s(((([02468])|(1[02468])|(2[024])):((00))))"; if(!measureDateTime.matches(timer)) flag=false; return flag; //(((([02468])|(1[02468])|(2[024])):((00))))"; } boolean validateWaterLevel(String waterLevel) { boolean flag=true; //匹配目标水位,实际水位,流量 String part1="(([1-9])|([1-9]\\d)|([1-9]\\d{2}))" + "|((([1-9])|([1-9]\\d)|([1-9]\\d{2}))\\.((000)|(00[1-9])|(0[1-9]\\d)|(0[1-9])|([1-9])|([1-9][1-9])|([1-9]\\d{2})))"; if(!waterLevel.matches(part1)) flag=false; return flag; } boolean validateGateOpening(String gateOpening) { boolean flag=true; //匹配开度 String part2="((([1-9])\\.([0-9][0-9]))/(([1-9])\\.([0-9][0-9])))"; if(!gateOpening.matches(part2)) flag=false; return flag; } } class DealData { StringBuilder sb; DealData(){} DealData(StringBuilder sb) { this.sb=sb; } StringBuilder getSb() { return this.sb; } void setSb(StringBuilder sb) { this.sb=sb; } void getDealDataResult() { } void computerData(HydrologicalInfo hydrologicalInfo[],int num) { int i;double Max=0; double total = 0; for(i=0;i<num;i++) { if(hydrologicalInfo[i].actualWaterLevel>Max) { Max=hydrologicalInfo[i].actualWaterLevel; } total=total+2*60*60*hydrologicalInfo[i].waterFlow; } System.out.printf("Max Actual Water Level:%.2f\n",Max); System.out.printf("Total Water Flow:%.2f",total); } } class HydrologicalInfo{ //LocalDateTime measureDateTime; double objectWaterLevel;double actualWaterLevel;double objectGateOpening;double actualGateOpening;double waterFlow; HydrologicalInfo(){} HydrologicalInfo(double objectWaterLevel,double actualWaterLevel,double objectGateOpening,double actualGateOpening,double waterFlow) { this.actualGateOpening=actualGateOpening; this.actualWaterLevel=actualWaterLevel; this.objectGateOpening=actualGateOpening; this.objectWaterLevel=objectWaterLevel; this.waterFlow=waterFlow; } double getObjectWaterLevel() { return this.objectWaterLevel; } void setObjectWaterLevel(double objectWaterLevel) { this.objectWaterLevel=objectWaterLevel; } double getActualWaterLevel() { return this.actualWaterLevel; } void setActualWaterLevel(double ActualWaterLevel) { this.actualWaterLevel=ActualWaterLevel; } double getObjectGateOpening() { return this.objectGateOpening; } void setObjectGateOpening(double objectGateOpening) { this.objectGateOpening=objectGateOpening; } double getActualGateOpening() { return this.actualGateOpening; } void setActualGateOpening(double actualGateOpening) { this.actualGateOpening=actualGateOpening; } double getWaterFlow() { return this.waterFlow; } void setWaterFlow(double WaterFlow) { this.waterFlow=WaterFlow; } }
在题目集4(7-1)中,主函数还是看起来比较繁琐,套了太多的循环和if-else,没有实现单一职责原则,这样可能造成后续改代码的过程中造成重大改动的问题。并且本题并没有完全按照解题报告中的写,例如我虽然创造了class HydrologicalInfo,但实际上并没有使用它,也只是在主函数中new了一个。如果是这样写的话,完全是可以不同到这个类的。
同样的问题也出现在了题目集6(7-5)中。
import java.util.Scanner; public class Main { public static void main(String[] args) { // TODO 自动生成的方法存根 Scanner in=new Scanner(System.in); double[] area=new double [100]; int a,b,c; int j=0; a=in.nextInt(); b=in.nextInt(); c=in.nextInt(); boolean flag=false; Circle C=new Circle(); Rectangle R=new Rectangle(); Triangle T=new Triangle(); if(a<0||b<0||c<0) System.out.println("Wrong Format"); else { for(int i=1;i<=a;i++) { double r=in.nextDouble(); C.setRadius(r); if(C.validata()) { //System.out.printf("%.2f ",C.getArea()); //System.out.print(C.getArea()+" "); area[j++]=C.getArea(); } else { flag=true; } } for(int i=1;i<=b;i++) { double w=in.nextDouble(); double l=in.nextDouble(); R.setWidth(w); R.setLength(l); if(R.validata()) { area[j++]=R.getArea(); //System.out.printf("%.2f ",R.getArea()); //System.out.print(R.getArea()+" "); } else { flag=true; } } for(int i=1;i<=c;i++) { double s1=in.nextDouble(); double s2=in.nextDouble(); double s3=in.nextDouble(); T.setSide1(s1); T.setSide2(s2); T.setSide3(s3); if(T.validata()) { area[j++]=T.getArea(); //System.out.printf("%.2f ",T.getArea()); //System.out.print(T.getArea()+" "); } else flag=true; } if(flag==true) { System.out.println("Wrong Format"); } else { SortandSum S=new SortandSum(); System.out.println("Original area:"); S.showdata(area,a+b+c); S.sum(area,a+b+c); area=S.sort(area,a+b+c); System.out.println(); System.out.println("Sorted area:"); S.showdata(area,a+b+c); S.sum(area,a+b+c); } } } } class SortandSum { void sum(double area[],int length) { double sum = 0; for(int i=0;i<length;i++) { sum+=area[i]; } System.out.println(); System.out.printf("Sum of area:%.2f",sum); //System.out.println("Sum of area:"+sum); } double[] sort(double area[],int length) { for(int i=0;i<length-1;i++) { for(int j=0;j<length-1-i;j++) { if(area[j]>area[j+1]) { double t=area[j]; area[j]=area[j+1]; area[j+1]=t; } } } return area; } void showdata(double area[],int length) { for(int i=0;i<length;i++) { System.out.printf("%.2f ",area[i]); } } } class Shape { public double getArea() { return 0; } public boolean validata() { return true; } public String toString() { return null; } } class Circle extends Shape { double radius; public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public double getArea() { double area; area=Math.PI*this.radius*this.radius; return area; } public boolean validata() { if(this.radius>0) return true; return false; } } class Rectangle extends Shape { double width; double length; public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } public double getArea() { double area; area=this.length*this.width; return area; } public boolean validata() { if(this.length>0&&this.width>0) return true; return false; } } class Triangle extends Shape { double side1; double side2; double side3; public double getSide1() { return side1; } public void setSide1(double side1) { this.side1 = side1; } public double getSide2() { return side2; } public void setSide2(double side2) { this.side2 = side2; } public double getSide3() { return side3; } public void setSide3(double side3) { this.side3 = side3; } public double getArea() { double area; double c=this.side1+this.side2+this.side3; double p=c/2.0; area=Math.sqrt(p*(p-this.side1)*(p-this.side2)*(p-this.side3)); return area; } public boolean validata() { if(this.side1+this.side2>this.side3&&this.side1+this.side3>this.side2&&this.side2+this.side3>this.side1) return true; return false; } }
太顺畅了,第六次的题目集,导致我没有看到本题的解题报告中所要求我们需要怎么写的要求,就按着我自己的思路写的。但也可以看到主函数中好几个循环。现在想想可以这样写,创建一个输入接口,接口中有这输入的方法,在每一个图形类的中去具体这个方法。这样在主函数中看的简单明了,修改起来也只是需要修改类中的图形类的方法,不会对其他的代码造成影响。
这次实验的日期的聚合二的地方有些不理解的地方,日期的聚合一和聚合二题目中虽然聚合的方式不同,但大部分核心的代码还是相同的。但聚合方式二中测试点日期越界,月越界没有过去。除此之外,在室友那了解到求日期的时候最好不要用一天一天的方式去加或者减,在数据量很大的时候,不能在pta规定的时间运行完,会出现运行超时的错误。感觉自己还是没有把java的单一职责贯彻到底,因为在上面的题目中,代码还是看起来太繁琐。
五、总结
本阶段三次题目集主要是加强了正则表达式的学习,学习怎样处理输入的数据,以及校验它。除此之外还有使用接口的方法。再次看自己的代码时还意识到自己写代码的规范不严谨,喜欢把代码都写在一堆里面,这不符合面向对象程序设计的思想,在以后的写代码过程中还是要思考清楚,尽量实现java的几个规则。

浙公网安备 33010602011771号