Text Analyzer
Completed
Read lines until a line END. Print the number of lines, the number of words, the 3 most frequent words (lower case, letters only, ties alphabetical) as word:count, and the average word length with 2 decimals.
Input
Lines of text, then END.
Output
Four lines.
Example
Input
The cat sat on the mat. The dog sat too! END
Output
2 10 the:3 sat:2 cat:1 2.90
Editor
Java
Hints
split("[^a-z]+") splits on anything that isn't a letter.
Sort entries by (-count, word) and take 3.
Solution explanation
This combines input loops, regex splitting, maps, streams and formatting.
Show solution
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int lines = 0;
List<String> words = new ArrayList<>();
String line;
while (!(line = sc.nextLine()).equals("END")) {
lines++;
for (String token : line.toLowerCase().split("[^a-z]+")) {
if (!token.isEmpty()) words.add(token);
}
}
Map<String, Integer> counts = new HashMap<>();
for (String w : words) counts.merge(w, 1, Integer::sum);
String top = counts.entrySet().stream()
.sorted((a, b) -> !a.getValue().equals(b.getValue()) ? b.getValue() - a.getValue() : a.getKey().compareTo(b.getKey()))
.limit(3)
.map(e -> e.getKey() + ":" + e.getValue())
.collect(Collectors.joining(" "));
double avg = words.stream().mapToInt(String::length).average().orElse(0);
System.out.println(lines);
System.out.println(words.size());
System.out.println(top);
System.out.printf("%.2f%n", avg);
}
}