Text Analyzer

Lab Java Advanced 30 points

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
Sample input available Sample output available
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);
    }
}
Output
Answer
HOME LEARN COMMUNITY DASHBOARD