大厂面试题目数组(从文件中找到重复次数最高的单词)
大厂面试题目数组(从文件中找到重复次数最高的单词)/** * 读取文件单词存储到List * @param fileName * @return */ public static List<String> list(String fileName) { List list = new ArrayList<String>(); try (BufferedReader br = new BufferedReader( new InputStreamReader( new DataInputStream( new FileInputStream(fileName))))) { // 单词分隔符为空格 Pattern pattern = Patter
今天给大家分享一道常问的面试题目:从文件中找到重复次数最高的单词。这道题目的解决方案很多,今天就跟大家分享2种解决方案,希望能够帮助大家。
方案一、使用Hashamp和Comparator实现这个解决方案最核心重要地方就是对Hashmap条目进行排序,因为Map.Entry没有实现Comparable接口,因此我们需要编写自己的自定义Comparator来对条目进行排序。
1. 使用IO流读取文件单词并统计单词重复次数输出到Hashmap
/**
* 读取文件单词使用Hashmap存储并统计重复次数
* @param fileName
* @return
*/
public static Map<String Integer> buildCountMap(String fileName) {
Map<String Integer> wordsMap = new HashMap<>();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(
new DataInputStream(
new FileInputStream(fileName))))) {
// 单词分隔符为空格
Pattern pattern = Pattern.compile("\\s ");
String line = null;
while ((line = br.readLine()) != null) {
line = line.toLowerCase();
String[] words = pattern.split(line);
for (String word : words) {
if (wordsMap.containsKey(word)) {
//存在单词,重复次数 1
wordsMap.put(word (wordsMap.get(word) 1));
} else {
//不存在,默认次数为1
wordsMap.put(word 1);
}
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
return wordsMap;
}
2、使用Comparator降序排列集合元素
/**
* 使用Comparator降序排序集合元素
* @param wordsMap
* @return
*/
public static List<Map.Entry<String Integer>> sort(Map<String Integer> wordsMap) {
List<Map.Entry<String Integer>> list = new ArrayList<>(wordsMap.entrySet());
Collections.sort(list new Comparator<Map.Entry<String Integer>>() {
@Override
public int compare(Map.Entry<String Integer> o1 Map.Entry<String Integer> o2) {
return (o2.getValue()).compareTo(o1.getValue());
}
});
return list;
}
3、测试结果
public static void main(String args[]) {
//方案一
Map<String Integer> wordsMap = buildCountMap("C:/demo/sample.txt");
List<Map.Entry<String Integer>> list = sort(wordsMap);
System.out.println("List of repeated word from file and their count");
for (Map.Entry<String Integer> entry : list) {
System.out.println(entry.getKey() " => " entry.getValue());
}
}
输出结果 :
这个解决方案会读取文本单词到List 重点是使用java8的stream 函数实现文件分类汇总后倒序排列集合元素。
1、读取文件单词存储到List
/**
* 读取文件单词存储到List
* @param fileName
* @return
*/
public static List<String> list(String fileName) {
List list = new ArrayList<String>();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(
new DataInputStream(
new FileInputStream(fileName))))) {
// 单词分隔符为空格
Pattern pattern = Pattern.compile("\\s ");
String line = null;
while ((line = br.readLine()) != null) {
line = line.toLowerCase();
String[] words = pattern.split(line);
for (String word : words) {
list.add(word);
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
return list;
}
2、使用Stream流汇总元素后降序排序
如果你熟悉JAVA8 Stream的话,可以使用stream函数collect group by 以及sorted功能实现。
(1)首先通过group by 统计List元素重复次数并输出到Map
(2)再把map元素遍历使用sorted倒序排列输出到LinkedHashmap就可以实现了
/**
* Stream汇总结合后倒序排列存储到LinkedHashMap
* @param wordsList
*/
public static void sort(List<String> wordsList){
//List元素group by统计单词的重复次数输出到Map
Map<String Long> map = wordsList.stream().collect(Collectors.groupingBy(Function.identity() Collectors.counting()));
//使用Stream.sorted倒序排列map条目到LinkedHashMap
Map<String Long> sortMap = new LinkedHashMap<>();
map.entrySet().stream().sorted(Map.Entry.<String Long>comparingByValue().reversed()).
forEachOrdered(e -> sortMap.put(e.getKey() e.getValue()));
sortMap.forEach((k v)->{
System.out.println("word=" k " count=" v);
});
}
3、测试结果
public static void main(String args[]) {
//方案二
sort(list("C:/demo/sample.txt"));
}
打印测试结果:
我们在面试写代码过程除了实现基本功能功能以外,面试官还会重点考察你的代码安全以及性能这些指标。所以这道题还需要注意以下几个点:
1. IO操作需要记得关闭流的正确方法。如果您使用的是Java 7,则只需使用 try-with-resource语句。
2. 本解决方案没有关注指定文件的大小,面试官可能会问你如果是大文件你又该如何处理呢。对于大文,如果使用上面的代码可能抛出java.lang.OutOfMemory的异常。
一种解决方案是分批执行此任务,例如首先读取20%的内容,找到最大重复的单词,然后读取下一个20%的内容,并考虑先前的最大值来找到重复的最大值。这样,您无需将所有单词存储在内存中,并且可以处理任何任意长度的文件。
3.注意泛型的使用,这样确保您的程序在编译时是正确的,而不是在运行时抛出异常。
这几点也是候选人平时编程习惯的体现,面试官通过你的代码就能看出候选人的编程功底,这些都是技术评级的重要参考标准之一。
结论:好了,今天给大家分享了如何从文件中找到重复次数最高的单词的两种解决方案,方案比较简单,希望能够帮助你。当然你可以参考以上思路尝试下其它的解决办法。