开始我的第二次博客吧,这次题目集真的是,每个题集都有一个卡你到死的题目,就比如题集4的第一题吧,真的是第一题就开始折磨。
7-1 水文数据校验及处理 (50 分)
这题的思路非常清晰,就是用正则表达式和分割函数来对字符串进行操作,但就是那一大摞的正则表达式真的是折磨人。先附上我的主函数
public static void main(String[] args) { // TODO 自动生成的方法存根 String adc; double mmax=0; double sum=0; int last=0; //ai a=new ai(); Scanner in=new Scanner(System.in); // String regex ="[1-9][0-9]{0,3}/(1[0-2]|[1-9])/([1-2][0-9]|3[0-1]|[1-9]) (2[0|2|4]|1{0,1}[0|2|4|6|8]|):00|";//折磨表达式//格式为“年/月/日时:分”,其中年份取值范围为[1,9999], //“年”非4位数时,之前不加“0”,“月”与“日”为一位数时之前也不加“0”,日期与时间之间有一个空格, //boolean flag = s.matches(regex);//判断功能 int cnt=0; while(true) { adc=in.nextLine(); if(adc.equals("exit")==true) { break; } cnt++; if(adc.length()==0) {continue; } String[]tmd=adc.trim().split("\\|"); if(!chong(tmd)){ System.out.println("Wrong Format"); System.out.println("Data:"+adc); continue; } for(int i=0;i<5;i++) { tmd[i]=tmd[i].trim(); } if(match(tmd,cnt,adc)) { sum = Double.valueOf(tmd[4])*60*60*2+sum; mmax= Math.max(mmax,Double.valueOf(tmd[2])); } else { last++; } } if(last==0) { System.out.printf("Max Actual Water Level:%.2f\n",mmax); System.out.printf("Total Water Flow:%.2f\n",sum); } }}
这是我的主函数部分,分别处理了数据合法性的判断,字符串的分割;左右空格的消除
分别解读下吧
for(int i=0;i<5;i++) { tmd[i]=tmd[i].trim(); }
这个循环一定要加!!!,不然最后一个点过不去,就是来处理分割完后的字符串左右多余的空格
然后
if(match(tmd,cnt,adc)) { sum = Double.valueOf(tmd[4])*60*60*2+sum; mmax= Math.max(mmax,Double.valueOf(tmd[2])); } else { last++; }
这是判断是否合法的函数,如果合法就对他进行操作。
然后判断是否合法的两个函数为下面的程序·。
public static boolean chong(String[] mmp) { if(mmp.length!=5) return false; return true; }
这个是判断是否是由4个‘|’分割成的5个字符串。
public static boolean match(String[] s,int cnt,String adc) { boolean flag=true; //String regex1="(?:((?:([1-9]([0-9]{0,3}))/((?:(([1-9]|(1[0-2]))/(?:([1-9]|([1-2][0-8])|19))))|(?:(([13578])|([1][02])(/31)))|(?:(([13-9]|1[02])/(29|30)))))(?:(?:( [02468]| 1[02468]| 2[02]|):00))))"; String regex="((?:([1-9][0-9]{0,3}))/((?:((1[0-2]|[1-9]))/(?:([1-2][0-9]|30|[1-9])))) (?:(?:([02468]|1[02468]|2[02]|):00)))"; //String regex="/(\d{4}-(((0(1|3|5|7|8))|(1(0|2)))(/((0[1-9])|([1-2][0-9])|(3[0-1])))?)|(((0(2|4|6|9))|(11))(/((0[1-9])|([1-2][0-9])|(30)))?)|((02)(-((0[1-9])|(1[0-9])|(2[0-8])))?))|(((([0-9]{2})((0[48])|([2468][048])|([13579][26]))|(((0[48])|([2468][048])|([3579][26]))00)))-02-29)/" if(s[0].matches(regex)==false) { System.out.printf("Row:%d,Column:1Wrong Format\n",cnt);//第一个 flag=false; } String regex1="(?:(?:(([1-9]([0-9]{0,2})))(?:((.[0-9]{1,3})?))))"; if(s[1].matches(regex1)==false) { System.out.printf("Row:%d,Column:2Wrong Format\n",cnt);//第二个 flag=false; } if(s[2].matches(regex1)==false) { System.out.printf("Row:%d,Column:3Wrong Format\n",cnt);//第三个 flag=false; } String regex2="(?:(([1-9])(?:(.[0-9]{2}))))"; String[] temp1= s[3].split("\\/"); if(s[3].contains("/")==false) { System.out.printf("Row:%d,Column:4Wrong Format\n",cnt);//第四个//中间分两个 flag=false; System.out.printf("Row:%d,Column:5Wrong Format\n",cnt);//第四个//中间分两个 flag=false; } else{ //String[] temp1= s[3].split("\\/"); if(temp1[0].matches(regex2)==false) { System.out.printf("Row:%d,Column:4Wrong Format\n",cnt);//第四个//中间分两个 flag=false; } if(temp1[1].matches(regex2)==false) { System.out.printf("Row:%d,Column:5Wrong Format\n",cnt);//第四个//中间分两个 flag=false; } } if(s[4].matches(regex1)==false) { System.out.printf("Row:%d,Column:6Wrong Format\n",cnt);//第五个 flag=false; } if(flag==false) { System.out.println("Data:"+adc); } else { if(Double.valueOf(temp1[0])<Double.valueOf(temp1[1])) { System.out.printf("Row:%d GateOpening Warning\n",cnt); } } return flag; }
其中包含了一堆正则表达式,用来判断每个数据都是否合法
然后当实际开度的值大于目标开度时,程序给出如下警告:
if(Double.valueOf(temp1[0])<Double.valueOf(temp1[1])) { System.out.printf("Row:%d GateOpening Warning\n",cnt); }
程序最后,如果所有数据全部合法,
就输出最后的结果
if(last==0) { System.out.printf("Max Actual Water Level:%.2f\n",mmax); System.out.printf("Total Water Flow:%.2f\n",sum); }
这算是挺有心路历程的一道题了,让我的正则表达式基础从0到0.1,感动自己这种鬼题都能拿满分。
题集四:7-2 日期问题面向对象设计(聚合一)
题集五:7-5 日期问题面向对象设计(聚合二)
这两个都是聚合设计的题目,但两个的设计确实不完全相同的,
这是第一张类图:
这是第二张类图:
聚合一使用一个一个聚合,来将所有类连接起来的·。先在dateutil类中聚合Day类,在再day类中聚合month类。再用month类聚合year类。这样虽然可能很方便,但是代码可维护性太差了,只要其中有一个类有需要改动的地方,其他类中使用那个改动函数或者改动变量的地方也要有所改动。
聚合二就是先用一个Dateutil父类写好所有的函数,然后用3个子类Day,month,Year来继承Dateutil父类。虽然可能每个子类的代码量非常的大,但是代码可维护性高。
题集四 7-3 图形继承
题集六 7-5 图形继承与多态
7-6 实现图形接口及多态性
第一题与第二题大体思路都一样,都是先写一个Shape类,然后再用几个类去继承他,运用了继承和多态的原理
二第三题就不一样了,需要用接口的思想, implements和interface。
题集五 7-4 统计Java程序中关键词的出现次数
这题真是写死我了。最后一个点硬是过不去哇(后面才知道是题目的样例有问题)
import java.util.*; import java.util.regex.*; public class Main { public static void main(String[] args) { Scanner in= new Scanner(System.in); String chong; String temp; StringBuffer gan=new StringBuffer(); while(true) { temp=in.nextLine(); if(temp.equals("exit")==true) { break; } String regex="(.*)//(.*)"; //String regex1="//"; if(temp.matches(regex)==true) { String temp1[]=temp.split("//"); gan=gan.append(temp1[0]+" "); continue; } gan=gan.append(temp+" "); } chong=gan.toString(); String match="\"(.*?)\""; Pattern pattern = Pattern.compile(match); Matcher matcher = pattern.matcher(chong); while (matcher.find()){ chong=chong.replace(matcher.group()," "); pattern = Pattern.compile("\"(.*?)\""); matcher = pattern.matcher(chong); } match="/\\**(.*?)/"; pattern=Pattern.compile(match); matcher = pattern.matcher(chong); while (matcher.find()) { chong=chong.replace(matcher.group()," "); pattern=Pattern.compile("/\\**(.*?)/"); matcher = pattern.matcher(chong); } chong=change(chong); if(chong.isEmpty()) { System.out.println("Wrong Format"); return ; } String[] word = chong.replaceAll("[\\W]"," ").split(" "); String []key= { "abstract","assert","boolean","break","byte","case","catch", "char","class","const","continue","default","do","double","else", "enum","extends","false","final","finally","float", "for","goto","if","implements","import","instanceof", "int","interface","long","native","new","null","package", "private","protected","public","return","short","static", "strictfp","super","switch","synchronized","this","throw", "throws","transient","true","try","void","volatile","while" }; Map<String, Integer> map=new HashMap<String, Integer>();//map int j,c; for( j=0;j<key.length;j++)map.put(key[j],0); for( int i = 0;i<word.length;i++) { for( j=0;j<key.length;j++) if(word[i].equals(key[j])) { c=map.get(key[j]); map.put(key[j], c+1); } } int bian[]=new int[10000]; for(int i=0;i<key.length;i++) { c=map.get(key[i]); bian[i]=c; if(c!=0) { System.out.printf("%d\t",c); System.out.println(key[i]); } } } }
这是我的代码,先用一堆正则表达式和replace函数来进行进行
注释中出现的关键字不用统计与
字符串中出现的关键字不用统计
最后再用一个map容器来进行字符的统计(不是题目需要才强行使用的)
原理也很简单啦,一个key值对应一个键值,他的底层原理好像使用哈希表写的。
这是map的代码:
String[] word = chong.replaceAll("[\\W]"," ").split(" "); String []key= { "abstract","assert","boolean","break","byte","case","catch", "char","class","const","continue","default","do","double","else", "enum","extends","false","final","finally","float", "for","goto","if","implements","import","instanceof", "int","interface","long","native","new","null","package", "private","protected","public","return","short","static", "strictfp","super","switch","synchronized","this","throw", "throws","transient","true","try","void","volatile","while" }; Map<String, Integer> map=new HashMap<String, Integer>();//map int j,c; for( j=0;j<key.length;j++)map.put(key[j],0); for( int i = 0;i<word.length;i++) { for( j=0;j<key.length;j++) if(word[i].equals(key[j])) { c=map.get(key[j]); map.put(key[j], c+1); } }
最后再按数组输出一下就行了
int bian[]=new int[10000]; for(int i=0;i<key.length;i++) { c=map.get(key[i]); bian[i]=c; if(c!=0) { System.out.printf("%d\t",c); System.out.println(key[i]); } }
题集6:
大部分还是正则表达式的训练,也让我重新还魂了,那么多字符实在有点记不清。也是好好的训练了一次,又重新学了一遍。
最后总结:这三次学习到的东西还是很多的,学会了继承,多态,接口,容器,正则表达式等知识。不过希望以后的题集题目的类型能够统一,能够先进行分块训练,再在最后一次题集进行所有类型的综合题目。我想这样效果更好
原文:https://www.cnblogs.com/chongchongtree/p/14708299.html