题目集4~6的总结性Blog
一、前言
题目集四
知识点考察:检验字符串的合法性以及类与类之间相互联系关系的操作,简单的数据合
法性判断与日期逻辑推理判断.其中字符串的StringBuilder应用以及字符串检验的使用
了正则表达式的应用,还有类与类之间的继承和聚合关系的实现去解决问题.
题目量:适中;难度:适中
题目集五
知识点考察:字符串的计数以及数组的合并还有数组的三种常用排序方法,其中字符串
的计数对于java中53个关键字计数,然后类与类之间的继承关系应用解决日期问题,日期
逻辑推理以及合法性检验.
题目量:适中;难度:适中
题目集六
知识点考察:
简单的字符串的正则表达式检验合法性还有字符串的排序.图形的继承与多态的使用解决
面积周长问题,简单的形状合法判断,抽象类的构造与抽象类方法的复写应用,还有与类有关
的接口的使用.
题目量:适中;难度:适中
二、设计与分析
题目集四7-1 水文数据校验及处理 (50 分)
提交代码分析:(代码注释以及图的分析)
1 import java.util.regex.Matcher; 2 import java.util.regex.Pattern; 3 import java.util.*; 4 public class Main{ 5 public static void main(String[] args) { 6 Scanner in=new Scanner(System.in); 7 String str; 8 StringBuilder sb= new StringBuilder(); 9 while(true){ 10 str = in.nextLine(); 11 // System.out.println(str); 12 if (str.equals("exit")) { //判断是否结束 13 break; 14 } 15 else if(str.length()==0) {//如果输入为空,则跳过此行继续1下一行 16 continue; 17 } 18 else { 19 sb.append(str);//有效则加入StringBuilder中 20 sb.append('\n');//并以\n来分割各行输入的数据 21 } 22 } 23 if(validate(sb)){//是否全部输入合法 24 DealDate data = new DealDate(sb);//全部合法则开始计算 25 data.getDealDateResult(); 26 } 27 } 28 public static boolean validate(StringBuilder sb) { 29 boolean flag=true; 30 String data = sb.toString(); 31 if(data.length()==0) { 32 System.out.println("Max Actual Water Level:0.00"); 33 System.out.printf("Total Water Flow:0.00"); 34 System.exit(0);//全部输入为空或多行空 35 } 36 String []x=new String[100000]; 37 String[] str = data.split("\n"); 38 for(int i=0;i < str.length; i++){ 39 CheckData checkData = new CheckData(str[i],i+1); 40 if(!checkData.validateData()) 41 flag=false; 42 } 43 return flag;//判断数据是否合法返回boolean型flag 44 } 45 } 46 class CheckData{ 47 private String data; 48 private int row; 49 public CheckData() { 50 51 } 52 public CheckData(String Data,int row) { 53 this.data = Data; 54 this.row = row; 55 } 56 public String[] getData() { 57 String [] str = data.split("\\|",5); 58 for(int i = 0;i<str.length;i++) { 59 str[i] = str[i].trim();//去除首尾空格 60 } 61 str[3]=str[3].trim(); 62 return str; 63 } 64 public void setData(String data,int row) { 65 this.data = data; 66 this.row = row; 67 } 68 public boolean validateWaterLevel(String waterLevel) { 69 return waterLevel.matches("(^[1-9][0-9]{1,2}|^[1-9])(\\.[0-9]{1,3})?$");//正则表达式检验字符串合法性 70 } 71 public boolean validateGateOpening(String gateOpening) { 72 return gateOpening.matches("^[1-9](\\.[0-9]{2})/[1-9](\\.[0-9]{2})$");//正则表达式检验字符串合法性 73 } 74 public boolean validateData() { 75 int flag1,k,s; 76 for( k=0,s=0;k<data.length();k++){ 77 if(data.charAt(k)=='|') 78 s++; 79 } 80 if(s!=4){ 81 System.out.println("Wrong Format"); 82 System.out.println("Data:"+this.data);//是否被|分成五部分 83 return false; 84 } 85 String []str = getData(); 86 // System.out.println(validateGateOpening(str[3]));//检验正确性 87 if(validateMeasureDateTime(str[0])&&validateWaterLevel(str[1])&&validateWaterLevel(str[2])&&validateGateOpening(str[3])&&validateWaterLevel(str[4])){ 88 return true; 89 } 90 else { 91 if (!validateMeasureDateTime(str[0]))//找出不合法的该部分 92 System.out.println("Row:"+this.row+",Column:1Wrong Format"); 93 if(!validateWaterLevel(str[1])) 94 System.out.println("Row:"+this.row+",Column:2Wrong Format"); 95 if(!validateWaterLevel(str[2])) 96 System.out.println("Row:"+this.row+",Column:3Wrong Format"); 97 if(!validateGateOpening(str[3])) { 98 if(!str[3].contains("/")){ 99 System.out.println("Row:"+this.row+",Column:4Wrong Format"); 100 System.out.println("Row:"+this.row+",Column:5Wrong Format"); 101 } 102 else{ 103 104 String[] c = str[3].split("/",2); 105 // System.out.println(c[0]+c[1]+"99999999999999"); 106 if(!c[0].matches("^[1-9]\\.\\d{2}$")) 107 System.out.println("Row:"+this.row+",Column:4Wrong Format"); 108 if(!c[1].matches("^[1-9]\\.\\d{2}$")) 109 System.out.println("Row:"+this.row+",Column:5Wrong Format"); 110 } 111 } 112 if(!validateWaterLevel(str[4])) 113 System.out.println("Row:"+this.row+",Column:6Wrong Format"); 114 System.out.println("Data:"+this.data); 115 return false; 116 } 117 } 118 public boolean validateMeasureDateTime(String measureDateTime) {//日期合法性的正则检验 119 Pattern p = Pattern.compile("(^[1-9]|^[1-9][0-9]{1,3})/((([13578]|1[02])/(1[0-9]|2[0-9]|3[0-1]|[1-9]))|(([469]|11)/(1[0-9]|2[0-9]|30|[1-9]))|(2/(1[0-9]|2[2-9]|[1-9])))[ ]([02468]|1[02468]|2[024]):00"); 120 Matcher m = p.matcher(measureDateTime); 121 if(!p.matcher(measureDateTime).matches()) { 122 return false; 123 } 124 m.find();//还要额外考虑是否闰年因为2月较特殊 125 String [] x = m.group().split("/",3); 126 String [] y = x[2].split(" "); 127 int a=Integer.parseInt(x[0]); 128 int b=Integer.parseInt(x[1]); 129 int c=Integer.parseInt(y[0]); 130 if(!(a%4==0&&a%100!=0||a%400==0) && b == 2&&c ==29) 131 return false; 132 return true; 133 } 134 public HydrologicalInfo toHydrologicalInfo() {//合法储存的方法 135 String [] str = getData(); 136 String [] str1 = str[3].split("/"); 137 String mesuareDateTime = str[0]; 138 double objectWaterLevel = Double.valueOf(str[1]); 139 double actualWaterLevel = Double.valueOf(str[2]); 140 double objectGateOpening = Double.valueOf(str1[0]); 141 double actualGateOpening = Double.valueOf(str1[1]); 142 double waterFlow = Double.valueOf(str[4]); 143 HydrologicalInfo hydrologicalInfo = new HydrologicalInfo(mesuareDateTime,objectWaterLevel,actualWaterLevel,objectGateOpening,actualGateOpening,waterFlow); 144 return hydrologicalInfo; 145 } 146 } 147 class HydrologicalInfo { //储存数据的类 148 private String measureDateTime; 149 private double objectWaterLevel; 150 private double actualWaterLevel; 151 private double objectGateOpening; 152 private double actualGateOpening; 153 private double waterFlow; 154 HydrologicalInfo(){ 155 156 } 157 HydrologicalInfo(String measureDateTime,double objectWaterLevel,double actualWaterLevel,double objectGateOping,double actualGateOping,double waterFlow){ 158 this.measureDateTime = measureDateTime; 159 this.objectWaterLevel = objectWaterLevel; 160 this.actualWaterLevel = actualWaterLevel; 161 this.objectGateOpening = objectGateOping; 162 this.actualGateOpening = actualGateOping; 163 this.waterFlow = waterFlow; 164 } 165 public void setMeasureDateTime(String measureDateTime){ 166 this.measureDateTime = measureDateTime; 167 } 168 public String getMeasureDateTime(){ 169 return this.measureDateTime; 170 } 171 172 public void setObjectWaterLevel(double objectWaterLevel) { 173 this.objectWaterLevel = objectWaterLevel; 174 } 175 public double getObjectWaterLevel() { 176 return this.objectWaterLevel; 177 } 178 179 public void setActualWaterLevel(double actualWaterLevel) { 180 this.actualWaterLevel = actualWaterLevel; 181 } 182 public double getActualWaterLevel() { 183 return this.actualWaterLevel; 184 } 185 186 public void setObjectGateOping(double objectGateOping) { 187 this.objectGateOpening = objectGateOping; 188 } 189 public double getObjectGateOping() { 190 return this.objectGateOpening; 191 } 192 193 public void setActualGateOping(double actualGateOping) { 194 this.actualGateOpening = actualGateOping; 195 } 196 public double getActualGateOping() { 197 return this.actualGateOpening; 198 } 199 200 public void setwaterFlow(double waterFlow) { 201 this.waterFlow = waterFlow; 202 } 203 public double getWaterflow() { 204 return this.waterFlow; 205 } 206 } 207 class DealDate{//用来计算数据的类 208 private StringBuilder sb; 209 public DealDate() { 210 211 } 212 public DealDate(StringBuilder sb) { 213 this.sb = sb; 214 } 215 public StringBuilder getSb() { 216 return sb; 217 } 218 public void setSb(StringBuilder sb) { 219 this.sb = sb; 220 } 221 public void getDealDateResult() { 222 HydrologicalInfo hydrologicalInfo[]=new HydrologicalInfo[10010]; 223 String data = sb.toString(); 224 String[] str = data.split("\n"); 225 for(int i=0;i < str.length; i++){ 226 str[i]=str[i].trim(); 227 CheckData checkData = new CheckData(str[i],i+1); 228 hydrologicalInfo[i] = checkData.toHydrologicalInfo(); 229 } 230 computeDate(hydrologicalInfo); 231 } 232 public void computeDate(HydrologicalInfo hydrologicalInfo[]) { 233 int i = 0; 234 int row = 1; 235 double sum = 0; 236 double max = hydrologicalInfo[0].getActualWaterLevel(); 237 for(i = 0;hydrologicalInfo[i]!=null;i++,row++) { 238 if(max<hydrologicalInfo[i].getActualWaterLevel()) 239 max = hydrologicalInfo[i].getActualWaterLevel(); 240 if(hydrologicalInfo[i].getActualGateOping() > hydrologicalInfo[i].getObjectGateOping()) { 241 System.out.println("Row:"+row+" GateOpening Warning"); 242 } 243 sum = sum+hydrologicalInfo[i].getWaterflow()*2*60*60; 244 } 245 System.out.println("Max Actual Water Level:"+String.format("%.2f",max)); 246 System.out.println("Total Water Flow:"+String.format("%.2f",sum));//用String.format保留两位小数 247 } 248 }
此题目使用了三个类(checkDate,DealDate,HydrologicalInfo)来解决问题,checkDate即检验字符串是否合法,DealDate计算合法的数据,HydrologicalInfo用来
储存数据,类与类之间无相关关系.不同的类完成不同的工作.

代码最大深度为5,此题目逻辑并不复杂,注意细节即可.
题目集四7-2 日期问题面向对象设计(聚合一)与题目集五7-2 日期问题面向对象设计(聚合二)
题目集四7-2 日期问题面向对象设计(聚合一)
思路:构建三个类构成一个日期类,然后使用日期类来解决前n天,后n天以及两个日期差值,由题目要求使用聚合关系,构造题目要求的类关系
计算前n天以及后n天使用日期的一天天往前推或者往后推来实现,而计算两个日期差值时,先是判断小的日期,再由小的日期一天天往下走,
使用一个计数的变量来计数,直到他们相等即退出返回该值可得出答案.
提交代码分析:
1 import java.util.Scanner; 2 public class Main { 3 public static void main(String [] args) { 4 Scanner in = new Scanner(System.in); 5 int choice = in.nextInt(); 6 int yearValue = in.nextInt(); 7 int monthValue = in.nextInt(); 8 int dayValue = in.nextInt(); 9 switch (choice) {//不同选择进行不同运算用switch语句比if语句更好 10 case 1:int n= in.nextInt(); 11 Day day = new Day();//创建三个类Day day,Month month,Year year.Day与month聚合,Month与Year聚合,再用DateUtil聚合类Day进行计算 12 day.setValue(dayValue); 13 Month month = new Month(); 14 month.setValue(monthValue); 15 Year year = new Year(); 16 year.setValue(yearValue); 17 month.setYear(year); 18 day.setMonth(month); 19 DateUtil dateutil = new DateUtil(); 20 dateutil.setDay(day);//聚合操作 21 dateutil.getDay().setMonth(month);//聚合操作 22 dateutil.getDay().getMonth().setYear(year); //聚合操作 23 if(!dateutil.checkInputValidity()) { 24 System.out.println("Wrong Format");//检验合法性 25 System.exit(0); 26 } 27 dateutil.getNextNday(n);//合法求下n天 28 System.out.println(dateutil.showDate());//输出结果 29 break; 30 case 2:int n1= in.nextInt(); 31 Day day1 = new Day();//同上创建计算 32 day1.setValue(dayValue); 33 Month month1 = new Month(); 34 month1.setValue(monthValue); 35 Year year1 = new Year(); 36 year1.setValue(yearValue); 37 month1.setYear(year1); 38 day1.setMonth(month1); 39 DateUtil dateutil1 = new DateUtil(); 40 dateutil1.setDay(day1); 41 dateutil1.getDay().setMonth(month1); 42 dateutil1.getDay().getMonth().setYear(year1); 43 if(!dateutil1.checkInputValidity()) {//检验合法 44 System.out.println("Wrong Format"); 45 System.exit(0); 46 } 47 dateutil1.getPreviousNday(n1);//求前n天 48 System.out.println(dateutil1.showDate());//输出结果 49 break; 50 case 3: int yearValue1 = in.nextInt(); 51 int monthValue1 = in.nextInt(); 52 int dayValue1 = in.nextInt(); 53 Day day2 = new Day();//创建两个DateUtil类,DateUtil类与day聚合,day与month聚合,month与year聚合 54 day2.setValue(dayValue); 55 Month month2 = new Month(); 56 month2.setValue(monthValue); 57 Year year2 = new Year(); 58 year2.setValue(yearValue); 59 month2.setYear(year2); 60 day2.setMonth(month2); 61 DateUtil dateutil2 = new DateUtil(); 62 dateutil2.setDay(day2); 63 dateutil2.getDay().setMonth(month2); 64 dateutil2.getDay().getMonth().setYear(year2); 65 if(!dateutil2.checkInputValidity()) {//检验合法 66 System.out.println("Wrong Format"); 67 System.exit(0); 68 } 69 Day day3 = new Day(); 70 day3.setValue(dayValue1); 71 Month month3 = new Month(); 72 month3.setValue(monthValue1); 73 Year year3 = new Year(); 74 year3.setValue(yearValue1); 75 month3.setYear(year3); 76 day3.setMonth(month3); 77 DateUtil dateutil3 = new DateUtil(); 78 dateutil3.setDay(day3); 79 dateutil3.getDay().setMonth(month3); 80 dateutil3.getDay().getMonth().setYear(year3); 81 if(!dateutil3.checkInputValidity()) {//同上 82 System.out.println("Wrong Format"); 83 System.exit(0); 84 } 85 System.out.println(dateutil2.getDaysofDates(dateutil3));//输出两日期差 86 break; 87 default : System.out.println("Wrong Format"); 88 break;//选择错误输出 89 } 90 } 91 } 92 class Day{//日期中日的类 93 private int value;//日的值 94 private Month month; //聚合的month类 95 int[] mon= {-1,31,28,31,30,31,30,31,31,30,31,30,31};//数组用来储存该月最大日期 96 public Day() {//无参构造 97 98 } 99 public Day(int yearValue,int MonthValue,int DayValue) {//有参构造 100 value = DayValue; 101 month.setValue(MonthValue); 102 month.getYear().setValue(yearValue); 103 } 104 public int getValue() {//setter与getter 105 return value; 106 } 107 public void setValue(int value) { 108 this.value = value; 109 } 110 public Month getMonth() { 111 return month; 112 } 113 public void setMonth(Month month) { 114 this.month = month; 115 } 116 public boolean validate() { 117 if(this.value<1||this.month.getValue()>12||mon[this.getMonth().getValue()]<this.value||(!this.month.getYear().isLeapYear()&&this.month.getValue()==2&&this.value==29)) 118 return false; 119 return true; 120 } 121 public void resetMin() {//设置该月最小值用来求下n天遍历 122 this.value = 1; 123 } 124 public void resetMax() {//设置为该月最大值用来求前n天遍历 125 this.value = this.mon[this.month.getValue()]; 126 } 127 public void dayIncrement() {//一天天加 128 this.value++; 129 } 130 public void dayRecduction() {//一天天减 131 this.value--; 132 } 133 } 134 class Month{//日期中月的类 135 private Year year;//聚合的year类 136 private int value;//值 137 public Month() {//无参构造 138 139 } 140 public Month(int yearValue,int monthValue) {//有参构造 141 value = monthValue; 142 year.setValue(yearValue); 143 } 144 public int getValue() {//setter与getter 145 return value; 146 } 147 public void setValue(int value) { 148 this.value = value; 149 } 150 public Year getYear() { 151 return year; 152 } 153 public void setYear(Year year) { 154 this.year = year; 155 } 156 public boolean validate() { 157 if(this.value<1||this.value>12) 158 return false; 159 return true; 160 } 161 public void resetMin() {//设置最小月用来遍历年 162 this.value = 1; 163 } 164 public void resetMax() {//设置最大月遍历年 165 this.value = 12; 166 } 167 public void monthIncrement() {//++ 168 this.value++; 169 } 170 public void monthRecduction() {//-- 171 this.value--; 172 } 173 } 174 class Year{ 175 private int value;//值 176 public Year() { 177 178 } 179 public Year(int value) { 180 this.value=value; 181 } 182 public int getValue() {//setter与getter 183 return value; 184 } 185 public void setValue(int value) { 186 this.value = value; 187 } 188 public boolean isLeapYear() { 189 if(this.value%400==0||this.value%4==0&&this.value%100!=0) 190 return true; 191 return false; 192 } 193 public boolean validata() {//年份限制 194 if(this.value<1900||this.value>2050) 195 return false; 196 return true; 197 } 198 public void yearIncrement() {//年++ 199 this.value++; 200 } 201 public void yearReduction() {//年-- 202 this.value--; 203 } 204 } 205 class DateUtil{ 206 private Day day; 207 public DateUtil() {//无参 208 209 } 210 public DateUtil(int d,int m,int y) {//有参 211 day.setValue(d); 212 day.getMonth().setValue(m); 213 day.getMonth().getYear().setValue(y); 214 } 215 public Day getDay() { 216 return day; 217 } 218 public void setDay(Day day) { 219 this.day = day; 220 } 221 222 public boolean checkInputValidity(){ 223 if(!this.day.validate()||!this.day.getMonth().validate()||!this.day.getMonth().getYear().validata()) 224 return false; 225 return true; 226 } 227 public boolean compareDates(DateUtil date) {//比较两个日期的大小用this关键字与传入的日期比较 228 if(this.day.getMonth().getYear().getValue() > date.day.getMonth().getYear().getValue()) 229 return true; 230 if (this.day.getMonth().getYear().getValue() == date.day.getMonth().getYear().getValue()) { 231 if (this.day.getMonth().getValue() > date.day.getMonth().getValue()) 232 return true; 233 if (this.day.getMonth().getValue() == date.day.getMonth().getValue()) { 234 if (this.day.getValue() >date.day.getValue()) 235 return true; 236 return false; 237 } 238 return false; 239 } 240 return false; 241 } 242 public boolean equalTwoDates(DateUtil date) {//判断两个日期是否相等 243 if(this.day.getMonth().getYear().getValue() == date.day.getMonth().getYear().getValue()&&this.day.getMonth().getValue() == date.day.getMonth().getValue()&&this.day.getValue() == date.day.getValue()) 244 return true; 245 return false; 246 } 247 public String showDate() {//输出 248 return day.getMonth().getYear().getValue()+"-"+day.getMonth().getValue()+"-"+day.getValue(); 249 } 250 public void getNextNday(int n) {//求下n天具体方法一天天走下去 251 int i,max; 252 for( i=0;i<n;i++) { 253 day.dayIncrement(); 254 if(day.getMonth().getValue()==2&&day.getMonth().getYear().isLeapYear())//闰年2月最大值为29需要修改max值 255 max=29; 256 else 257 max=day.mon[day.getMonth().getValue()]; 258 if(day.getValue()>max) { 259 day.resetMin(); 260 day.getMonth().monthIncrement(); 261 if(day.getMonth().getValue()>12) { 262 day.getMonth().resetMin(); 263 day.getMonth().getYear().yearIncrement(); 264 } 265 } 266 } 267 268 } 269 public void getPreviousNday(int n) {//求前n天具体方法一天天回去
270 for(int i=0;i<n;i++) { 271 day.dayRecduction(); 272 if(day.getValue()<1) { 273 day.getMonth().monthRecduction(); 274 if(day.getMonth().getValue()<1) { 275 day.getMonth().resetMax(); 276 day.getMonth().getYear().yearReduction(); 277 } 278 if(day.getMonth().getValue()==2&&day.getMonth().getYear().isLeapYear())//同样考虑闰年2月 279 day.setValue(29); 280 else 281 day.resetMax(); 282 } 283 } 284 } 285 public int getDaysofDates(DateUtil date) {//求两个日期差的方法 286 int i; 287 DateUtil dateUtil1 = this; 288 DateUtil dateUtil2 = date; 289 if (this.compareDates(date)) {//判断日期大小 290 dateUtil1 = date;//小 291 dateUtil2 = this;//大 292 } 293 for(i=0;!dateUtil1.equalTwoDates(dateUtil2);i++) {//一天天走下去用i计数下去直到他们相等return i的值即为答案 294 dateUtil1.getNextNday(1); 295 } 296 return i; 297 } 298 }

DateUtil与Day聚合,Day与Month聚合,Month与Year聚合.

最大复杂度为5也是简单的逻辑运算注意类与类之间的private属性操作
2、日期聚合二
题目差不多,类与类之间的聚合关系不同.
核心算法差不多一样,注意类的聚合关系与上次不同,此处不放代码了.
题目二代码分析:DateUtil直接与三个类(Day,Year,Month)聚合,注意构造关系和类中方法位置的改变即可.

两题目优劣比较:
我认为聚合一操作麻烦,DateUtil不能直接调用相关的类而是通过Day各种调用Month与Year中的值和方法,类与类之间耦合性较高,多此一举.故劣处大不方便
聚合二直接通过DateUtil聚合三个类(Day,Year,Month)简单快捷,,类与类之间耦合性较低,我认为聚合二是较好的.
最大圈复杂度为5,此题目也是简单运算,关键是要理解类的继承
题目集六7-5图形继承与多态
设计思路:使用类的继承与多态完成题目,首先构建一个抽象的Shape类以及创建一个泛型,泛型装着为Shape类的对象,
抽象类对象中有四个方法,其中两个为抽象的方法,两个为静态的方法,之后再构造三个子类,子类实现了抽象的方法,父
类中的两个静态方法一个用来计算总面积,另一个输出计算数据结果题目要求对泛型中的Shape类的面积而对于Shape
进行排序,故要使用接口Comparable,再复写其中的comparaTo方法即可完成题目要求.
提交代码分析:
1 import java.util.ArrayList; 2 import java.util.Arrays; 3 import java.util.Collections; 4 import java.util.Scanner; 5 6 public class Main { 7 8 public static void main(String[] args) { 9 Scanner in = new Scanner(System.in); 10 int i,sum1,sum2,sum3; 11 int a = in.nextInt(); 12 int b = in.nextInt(); 13 int c = in.nextInt(); 14 sum1=a; 15 sum2=a+b; 16 sum3=a+b+c; 17 if(sum3<0){//计算出三类图形的个数如果小于0则输出"Wrong Format" 18 System.out.println("Wrong Format"); 19 System.exit(0); 20 } 21 ArrayList<Shape>list = new ArrayList<Shape>();//应题目要求使用泛型,把Shape类对象放入list中. 22 for( i=0;i<a;i++) {//创建形状为圆的类 23 double radius = in.nextDouble(); 24 list.add(new Circle(radius)); 25 } 26 for( i=a;i<a+b;i++) {//创建形状为矩形的类 27 double width = in.nextDouble(); 28 double length = in.nextDouble(); 29 list.add( new Rectangle(width,length)); 30 } 31 for(i=a+b;i<a+b+c;i++) {//创建形状为三角形的类 32 double side1= in.nextDouble(); 33 double side2 = in.nextDouble(); 34 double side3 = in.nextDouble(); 35 list.add(new Triangle(side1,side2,side3)); 36 } 37 for (i=0;i<list.size();i++) {/检验所有图形数据是否合法 38 if(!list.get(i).validate()) { 39 System.out.println("Wrong Format"); 40 System.exit(0); 41 } 42 } 43 Shape.toString(list,sum3); 44 } 45 46 } 47 abstract class Shape implements Comparable{//抽象类Shape,并接入了接口Comparable,目的是完成题目要求的对Shape类排序,故要接入Comparable接口重写该接口中的compareTo方法 48 public abstract double getArea(); 49 public abstract boolean validate(); 50 @Override 51 public int compareTo(Object o) { 52 Shape s = (Shape) o; 53 if (this.getArea()> s.getArea()) {//按Shape类中的Area属性从小到大排序 54 return -1; 55 } 56 return 1; 57 } 58 public static double sumgetArea(ArrayList<Shape> list,int sum3) { 59 int i; 60 double sum; 61 for( i=0,sum=0;i<sum3;i++)//获得各个Shape的面积总和 62 sum+=list.get(i).getArea(); 63 return sum; 64 } 65 public static void toString(ArrayList<Shape> list,int sum3) {//输出计算结果 66 System.out.println("Original area:"); 67 for(int i=0;i<list.size();i++) 68 System.out.print(String.format("%.2f ",list.get(i).getArea()));//使用String.format保留两位小数 69 System.out.println(); 70 System.out.print("Sum of area:"+String.format("%.2f\n",sumgetArea( list, sum3))); 71 System.out.println("Sorted area:"); 72 Collections.sort(list); 73 for(int i=0;i<list.size();i++) 74 System.out.print(String.format("%.2f ",list.get(i).getArea())); 75 System.out.println(); 76 System.out.print("Sum of area:"+String.format("%.2f\n",sumgetArea( list, sum3))); 77 } 78 } 79 class Circle extends Shape{//圆的类继承了Shape 80 private double radius; 81 public Circle() {//无参构造 82 83 } 84 public Circle(double radius) {//有参构造 85 this.radius = radius; 86 } 87 public double getRadius() {//一些setter与getter 88 return radius; 89 } 90 public void setRadius(double radius) { 91 this.radius = radius; 92 } 93 @Override 94 public double getArea() { 95 // TODO Auto-generated method stub 96 return Math.PI*radius*radius; 97 } 98 @Override 99 public boolean validate() { 100 // TODO Auto-generated method stub 101 if(radius<=0) 102 return false; 103 else 104 return true; 105 } 106 } 107 class Rectangle extends Shape{//矩形图形继承Shape类 108 private double width; 109 private double length; 110 public Rectangle(double width,double length) {//有参构造 111 this.width = width; 112 this.length = length; 113 } 114 public double getWidth() {//一些setter与getter 115 return width; 116 } 117 public void setWidth(double width) { 118 this.width = width; 119 } 120 public double getLength() { 121 return length; 122 } 123 public void setLength(double length) { 124 this.length = length; 125 } 126 @Override 127 public double getArea() { 128 // TODO Auto-generated method stub 129 return width*length; 130 } 131 @Override 132 public boolean validate() { 133 // TODO Auto-generated method stub 134 if(width<=0||length<=0) 135 return false; 136 else 137 return true; 138 } 139 } 140 class Triangle extends Shape{//三角形继承Shape类 141 private double side1; 142 private double side2; 143 private double side3; 144 public Triangle(double side1,double side2,double side3) {//有参构造 145 this.side1 = side1; 146 this.side2 = side2; 147 this.side3 = side3; 148 } 149 public double getSide1() {//一些setter与getter 150 return side1; 151 } 152 public void setSide1(double side1) { 153 this.side1 = side1; 154 } 155 public double getSide2() { 156 return side2; 157 } 158 public void setSide2(double side2) { 159 this.side2 = side2; 160 } 161 public double getSide3() { 162 return side3; 163 } 164 public void setSide3(double side3) { 165 this.side3 = side3; 166 } 167 @Override 168 public double getArea() { 169 // TODO Auto-generated method stub 170 double p=(side1+side2+side3)/2; 171 return Math.sqrt(p*(p-side1)*(p-side2)*(p-side3)); 172 } 173 @Override 174 public boolean validate() { 175 // TODO Auto-generated method stub 176 double [] a = new double [3]; 177 a[0]= side1; 178 a[1]=side2; 179 a[2]=side3; 180 Arrays.sort(a); 181 if(a[0]+a[1]<=a[2]||a[0]<0||a[1]<0||a[2]<0)//对于边长排序之后只需判断a[0]+a[1]<=a[2]和边长是否小于0即可 182 return false; 183 else 184 return true; 185 } 186 }

所谓的“多态”,简单的理解就是对象在不同情况下的不同表现,具体体现在定义和功能两个方面
Circle,Recetangle,Triangle,三个类继承了Shape类,并在解题过程中使用了多态解决问题.在排序方
面重写了Comparable接口中的compareTo方法,按照Shape中的Area的值排序.

最大圈复杂度为5还是并不复杂理解了类之间的联系继承与多态再仔细些就ok了
题目集六7-6实现图形接口及多态性
通过学习接口后这题就是对接口的一个简单应用题目较为简单完整代码就不放置了.
思路分析:构建一个接口,里面放置抽象getArea()方法,再由接入接口的两个类实现接口中的方法即可
分析部分提交代码:
1 interface GetArea {//定义一个接口使用关键字interface 2 public abstract double getArea();//接口中的方法一般是抽象的方法类通过接入接口之后可重写其方法 3 }
4 class Circle implements GetArea//接入接口使用关键字implements
5 class Rectangle implements GetArea//同上

两个类简单接入接口的使用

正则表达式技术的分析总结
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、
将匹配的子串替换或者从某个串中取出符合某个条件的子串等
(使用时不能忘记加入相关的包import java.util.regex.Matcher;import java.util.regex.Pattern;)
普通字符,普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号
特殊字符特殊字符就是一些有特殊含义的字符,如果要查找字符串中的 * 符号,则需要对 * 进行转义,即在其前加一个 \
限定符,限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种
如需匹配或检验一个合法的字符串可以使用String.matches(String regex)
如需替换一个匹配的字符串可以使用String.replaceAll(String regex,String replacement)
如需切割一个匹配的字符串可以使用String.spilt(String regex)方法来完成
如需使用全部所匹配的字符串可使Pattern p = Pattern.compile,Matcher m = p.matcher(String) , m.find(),m.group()方法进行操作;
匹配的正则表达式需要自己构造,方法有很多,构造符合模板即可
具体实例分析
1 Pattern p = Pattern.compile("(^[1-9]|^[1-9][0-9]{1,3})/((([13578]|1[02])/(1[0-9]|2[0-9]|3[0-1]|[1-9]))|(([469]|11)/(1[0-9]|2[0-9]|30|[1-9]))|(2/(1[0-9]|2[2-9]|[1-9])))[ ]([02468]|1[02468]|2[024]):00"); 2 Matcher m = p.matcher(measureDateTime); 3 if(!p.matcher(measureDateTime).matches()) { 4 return false; 5 } 6 m.find(); 7 String [] x = m.group().split("/",3);
1 String []x= str.split("/\\*.*\\*/|//.*|\"([^\"])*\"",100); 2 if(a.matches("[1-9]\\d{4,14}"))
更多详细具体用法还得个人继续思考学习
题目集5(7-4)中Java集合框架应用的分析总结
应用题目要求需使用List、Set或Map中一种或多种,对于此题目我的思路是使用哈希表来解决此问题
首先,什么是Map和HashMap?
- Map<K, V>是一个以 键值(Key)-数值(Value) 对应形式存储数据的接口。 在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value。
- HashMap是Map<K, V>的实现类。(Hashtable也是Map<K, V>的实现类) HashMap存储数据采用哈希表结构 ,元素的存取顺序不能保证一致。但键值是唯一、不重复的。导入Map和HashMap并建立哈希表
导入Map和HashMap并建立哈希表
不能忘记包
1 import java.util.HashMap; 2 import java.util.Map;
创建一个哈希表Map<String, Integer> Ages = new HashMap<String, Integer>();
常用方法
| Type | Method |
|---|---|
| Value | get(Object key) 返回键映射的值,如果该键没有映射值,则返回null |
| Value | put(K key, V value) 将键和值建立映射关系,如果键是第一次存储,就直接存储元素,返回null; 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值 |
| Value | remove(Object key) 如果对应键存在映射关系的值,则将其移除,并返回值 |
| boolean | containsKey(Object key) 是否存在特定的key |
| boolean | containsValue(Object value) 是否存在特定的value |
| boolean | isEmpty() 判断集合是否为空 |
题目具体分析:
1 for( int j=0;j<kw.length;j++) 2 map.put(kw[j], 0);//放置String 3 for(int i=0;i<str5.length;i++) { 4 for( int j=0;j<kw.length;j++) { 5 if(str5[i].equals(kw[j])){ //相等就value加1 6 s=map.get(kw[j]); 7 map.put(kw[j], s+1); 8 } 9 } 10 } 11 for(int i=0;i<kw.length;i++) { 12 if(map.get(kw[i])>0) { 13 System.out.println(map.get(kw[i])+"\t"+kw[i]);//hashmap获得String和value 14 } 15 }
三.采坑心得
水文数据检验时输入为空时需要跳过该行或者全为空时需要输出两组数据都为0

1 if(data.length()==0) { 2 System.out.println("Max Actual Water Level:0.00"); 3 System.out.printf("Total Water Flow:0.00"); 4 System.exit(0); 5 }

对于统计关键字的次数中,代码注释是会换行的故删除注释时需要跨行考虑而不是一行行的处理
![]()
改进:使用StringBuilder来添加每一行,而不是直接对nextLine处理,跨行处理
1 Pattern p=Pattern.compile("/\\*(.*){0,1}\\*/"); 2 Matcher m=p.matcher(str1); 3 while(m.find()) { 4 str1=str1.replace(m.group()," "); 5 p=Pattern.compile("/\\*(.*){0,1}\\*/"); 6 m=p.matcher(str1); 7 }
先全部放入一行当中,等处理完换行注释后再切割每一行
![]()
对于某泛型其中的一个或多个属性排序不能直接使用sort方法,需要重写Comparable接口中的compareTo方法
改正前代码图片:

改正后代码图片:

总结:这次采坑两处是逻辑不够严谨,之后应当更加注意细节处理才行,还有一处为知识上的漏洞,通过学习该知识后补上.
四.改进建议
对于日期类题目求前n天以及后n天可以不必一天天循环走下去,可直接由该月最小天到该月最大天数,然后相加它们的差值即可
对于一些for循环语句中可以使用其他的进行循环例如迭代器进行list循环
逻辑推理要求更高跟需要细致的思考分类,代码规范继续规范改正
五.总结与分析
通过了这三次的题目集训练之后,我学到了很多,我理解到了类与类之间的关系,明白了聚合关系,所谓聚合
关系:当对象A被加入到对象B中,成为对象B的组成部分时,对象B和对象A之间为聚合关系.聚合是关联关
系的一种,是较强的关联关系,强调的是整体与部分之间的关系。之后又学习了继承关系,理解了继承关系,
知道了继承即多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义
这些属性和行为.而继承的好处:1提高了代码的复用性2提高了代码维护性3类和类产生这种关系,是多态
的前提条件!多态此时也应运而生,所谓的“多态”,简单的理解就是对象在不同情况下的不同表现,具体体
现在定义和功能两个方面,简单的总结一下,多态可以用“三个定义和两个方法”来总结.三个定义分别是父
类定义子类构建,接口定义实现类构建和抽象类定义实体类构建,而两个方法分别是方法重载和方法重写.
我期待着明天,继续努力学习java!
教学改进建议及意见:老师已经听取了我们大部分同学的建议,降低了题目集难度,而我认为难度降低了
题目量应该多一些,毕竟学知识可没那么简单,需要多思考多练习.

浙公网安备 33010602011771号