Text Analyzer

Lab C++ Advanced 30 points

Read lines until END. Print the number of lines and words, the 3 most frequent words (lower case, letters only, ties alphabetical) as word:count, and the average word length (2 decimals).

Input

Lines, 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
C++

Hints

Build words character by character; a non-letter ends the current word.

Stop reading at the line END.

Solution explanation

Copying a map into a vector of pairs lets you sort by count.

Show solution
#include <iostream>
#include <iomanip>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>
using namespace std;

int main() {
    string line;
    int lines = 0;
    vector<string> words;
    while (getline(cin, line) && line != "END") {
        lines++;
        string word;
        for (char c : line + " ") {
            if (isalpha(static_cast<unsigned char>(c))) {
                word += static_cast<char>(tolower(c));
            } else if (!word.empty()) {
                words.push_back(word);
                word.clear();
            }
        }
    }
    map<string, int> counts;
    size_t letters = 0;
    for (const auto &w : words) {
        counts[w]++;
        letters += w.size();
    }
    vector<pair<string, int>> ranked(counts.begin(), counts.end());
    sort(ranked.begin(), ranked.end(), [](const auto &a, const auto &b) {
        if (a.second != b.second) return a.second > b.second;
        return a.first < b.first;
    });
    cout << lines << "\n" << words.size() << "\n";
    for (size_t i = 0; i < ranked.size() && i < 3; i++) {
        cout << (i ? " " : "") << ranked[i].first << ":" << ranked[i].second;
    }
    cout << "\n" << fixed << setprecision(2) << (words.empty() ? 0.0 : double(letters) / words.size()) << "\n";
    return 0;
}
Output
Answer
HOME LEARN COMMUNITY DASHBOARD