1、题目
请编写程序,对一段英文文本,统计其中所有不同单词的个数,以及词频最大的前10%的单词。
所谓“单词”,是指由不超过80个单词字符组成的连续字符串,但长度超过15的单词将只截取保留前15个单词字符。而合法的“单词字符”为大小写字母、数字和下划线,其它字符均认为是单词分隔符。
输入格式:、
输入给出一段非空文本,最后以符号
#
结尾。输入保证存在至少10个不同的单词。输出格式:
在第一行中输出文本中所有不同单词的个数。注意“单词”不区分英文大小写,例如“PAT”和“pat”被认为是同一个单词。
随后按照词频递减的顺序,按照
词频:单词
的格式输出词频最大的前10%的单词。若有并列,则按递增字典序输出。输入样例:
This is a test. The word "this" is the word with the highest frequency. Longlonglonglongword should be cut off, so is considered as the same as longlonglonglonee. But this_8 is different than this, and this, and this...# this line should be ignored.
输出样例:(注意:虽然单词the
也出现了4次,但因为我们只要输出前10%(即23个单词中的前2个)单词,而按照字母序,the
排第3位,所以不输出。
23 5:this 4:is
2、题目解读
题目要求我们从一段非空文本中,去统计其中所有不同单词的个数,并且以符号
#
结尾,而且长度超过15的单词将只截取保留前15个单词字符。最后 按照词频递减的顺序 按词频:单词
输出词频最大的前10%的单词。注意“单词”不区分英文大小写第一眼看到这题我的想法就是怎么去读取数据,毕竟第一次做类似的题目,然后我就去试,发现通过while循环去获取输入,然后读取到#符号就结束循环,发现这样可以正确读取数据。我是使用nextLine()来的输入,因为后面可以去添加统计更加方便。然后每读取一行就通过Hashmap来存储这些不同单词的个数。然后去进行排序,先比较词频大小再比较单词字典排列顺序。
3、代码
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); HashMap<String,Integer> map=new HashMap<>(); //设置一个标准,当b为0是即是退出while循环的时候, // 99999应该远大于题目所给的输入行数 int b=99999; while (sc.hasNext()){ String s=sc.nextLine(); //将所有字符串都变成小写 s=s.toLowerCase(); //判断是否有# if (s.contains("#")){ //如果有就使用substring方法截取字符串,因为还有部分字符串需要添加 //并且将b的之改为1,则下下一次循环将不会添加向Hashmap中添加元素 s=s.substring(0,s.indexOf("#")); b=1; } if (b==0){ break; } if (b>0){ //将各个单词分开 String[] ss=s.split(" "); for (int j=0;j<ss.length;j++){ //去除其他的单词分隔符,将其变成空格 ss[j]=ss[j].replaceAll("[^a-zA-Z_0-9]"," "); String a=ss[j]; //再一次将各个单词分开 //如:“this”is->this is;着就需要再一次用到split方法 String[] sss=a.split(" "); for(int i=0;i<sss.length;i++){ //截取前15个字符 if (sss[i].length()>15) sss[i]=sss[i].substring(0,15); //正常向HashMap添加单词 //不能向其中添加 空 if (!Objects.equals(sss[i], "")){ if (!map.containsKey(sss[i])){ map.put(sss[i],1); }else { map.put(sss[i],map.get(sss[i])+1); }}} } b--; } } //输出单词的个数 System.out.println(map.size()); //将HashMap的键值对取出放入List集合中 //方便去进行排序 List<Map.Entry<String,Integer>> list = new ArrayList<>(map.entrySet()); //传入比较器 list.sort((o1, o2) -> { //先判断词频是否相同,再通过compareTo方法比较两个单词的字典顺序 if (o1.getValue().equals(o2.getValue())){ return o1.getKey().compareTo(o2.getKey()); } //比较词频 return o2.getValue() - o1.getValue(); }); //通过Iterator迭代器进行输出 Iterator<Map.Entry<String, Integer>> iter = list.iterator(); //题目要求输出单词数目的10% int n=map.size()/10; while(iter.hasNext()){ Map.Entry<String, Integer> item = iter.next(); if (n==0) break; String key = item.getKey(); int value = item.getValue(); System.out.println(value+":"+key); n--; } } }
以上都是我个人的解题思路,有什么不足或者建议可以评论或者私信,一起交流学习