Text Analyzer
Completed
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
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;
}