import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Problem53 { public static void main(String[] args) { Scanner in=new Scanner(System.in); String important="abstract assert boolean break byte case catch char class const continue default do " + " double else enum extends final finally float for goto if implements import instanceof int " + "interface long native new package private protected public return strictfp short static super " + "switch synchronized this throw throws transient try void volatile while true false null"; String []end=important.split(" ");//因为粘贴下来的关键字之间有两个空格,所以切开来预处理,再放入映射容器中
//除了下面2种排序方法,还有很多方法完成排序
/*
一:对end数组使用sort,在关键字放入映射之前就完成排序
二:在新建map对象时,使用自定义比较器构建对象,(HashMap,LinkedMap不支持)
如new TreeMap<String,Integer>(String::compareTo) 这里使用了方法引用
或者 new TreeMap<String,Integer>((u,v)->{return u.compareTo(v);});//使用了Lamba表达式
.......
*/ Map<String,Integer> mp=new TreeMap<String,Integer>(); for(String e:end) mp.put(e,0); String s=null; int flag=0;//检查是否有关键字出现过 StringBuilder t=new StringBuilder();//用来完成字符串拼接 while(!(s=in.nextLine().trim()).equals("exit")){ //有第一种注释符号,跳出 if(s.matches(".*//.*")) continue;//当然这里并不严谨,毕竟//注释可以放在有效代码后面 t.append(s+" ");//将该字符串与下一行字符串隔开 } //替换/**/ s=t.toString(); s=change(s);//要过最后一个测试点的特殊处理
Pattern p=Pattern.compile("/\\*(.*)?\\*/"); Matcher m=p.matcher(s); while(m.find()){ s=s.replace(m.group()," "); m=p.matcher(s); } //替换""字符串 p=Pattern.compile("\"(.*?)\""); m=p.matcher(s); while(m.find()){ s=s.replace(m.group()," "); m=p.matcher(s); } if(s.length()==0){ System.out.print("Wrong Format");System.exit(0);} s=s.replaceAll("\\p{P}"," ");//替换掉所有的标点符号,$,_可以保留,但此题可以不考虑 //否则获得处理后的字符串 String[] temp=s.split("\\s+"); for(String e:temp) if(mp.containsKey(e)) { mp.put(e,mp.get(e)+1);flag=1; }//找到关键字,取出对应的值+1 //对输出情况进行分类 if(flag==0) System.exit(0);//有代码,但是没有关键字 //有关键字,将map转换为map.Entry<String,Integer>元素的列表,同时通过重写CompareTo方法,来使用sort对键进行排序
//map.entrySet()方法返回一个key,value键值对应的集合 List<Map.Entry<String, Integer>> list= new ArrayList<Map.Entry<String, Integer>>
//通配泛型,表示继承了Map.Entry(String,Integer)的接口或其本身
((Collection<? extends Map.Entry<String, Integer> >) mp.entrySet());
//排序方法一:使用匿名内部类简化继承Comparator泛型接口的实现 list.sort((o1, o2) -> o2.getKey().compareTo(o1.getKey()));//优化为使用lamba表达式 //排序方法二:排序和输出等操作,一起优化为使用流计算 // list.stream().sorted((o1,o2)->{return o1.getKey().compareTo(o2.getKey());}).filter(u->{return u.getValue()!=0;}) // .forEach(u->{ System.out.printf("%d\t%s\n",u.getValue(),u.getKey()); }); //打印有效关键字,如果使用了法二,下面的输出不需要 for(int i=list.size()-1;i>=0;i--){ if(list.get(i).getValue()==0) continue; System.out.printf("%d\t",list.get(i).getValue()); System.out.println(list.get(i).getKey()); } }
//专为最后一个测试点写的特殊处理 static String []special = {"\\$","_","int\\(\\)","boolean\\(\\)","double\\(\\)","float\\(\\)","byte\\(\\)","long\\(\\)","short\\(\\)","\\*"}; public static String change(String s){ if (s.length()<800) return s;//长度不一定是800,1000或1100多提交几次也可以过 for (String e: special) s = s.replaceAll(e, "SBTIMU"); return s; } }
贴一张提交图: