| 22 | #include <utility> |
| 23 | |
| 24 | int main() |
| 25 | { |
| 26 | std::string text; // Stores input prose or poem |
| 27 | std::cout << "Enter a poem or prose over one or more lines.\n" |
| 28 | << "Terminate the input with #:\n"; |
| 29 | getline(std::cin, text, '#'); |
| 30 | |
| 31 | std::map<char, std::vector<std::string>> lists; |
| 32 | |
| 33 | // Extract words and store in the appropriate list |
| 34 | const std::string_view separators {" \n\t,.\"?!;:"}; // Separators between words |
| 35 | size_t start {}; // Start of a word |
| 36 | size_t end {}; // separator position after a word |
| 37 | while (std::string::npos != (start = text.find_first_not_of(separators, start))) |
| 38 | { |
| 39 | end = text.find_first_of(separators, start+1); |
| 40 | const auto word{ text.substr(start, end - start) }; |
| 41 | const auto letter{ static_cast<char>(std::toupper(word[0])) }; |
| 42 | lists[letter].push_back(word); |
| 43 | start = end; |
| 44 | } |
| 45 | |
| 46 | // List the words in order 5 to a line |
| 47 | const size_t perline {5}; |
| 48 | |
| 49 | /* Option 1: use a loop similar to the original one */ |
| 50 | const std::string_view letters{ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" }; |
| 51 | for (char letter : letters) |
| 52 | { |
| 53 | if (!lists.contains(letter)) |
| 54 | continue; |
| 55 | |
| 56 | size_t count {}; // Word counter |
| 57 | for (const auto& word : lists[letter]) |
| 58 | { |
| 59 | if (count++ % perline == 0 && count != 1) |
| 60 | std::cout << std::endl; |
| 61 | std::cout << word << ' '; |
| 62 | } |
| 63 | std::cout << std::endl; |
| 64 | } |
| 65 | |
| 66 | std::cout << std::endl; |
| 67 | |
| 68 | /* Option 2: take advantage of the fact that the keys are already sorted in the map */ |
| 69 | for (const auto& [letter, list] : lists) |
| 70 | { |
| 71 | size_t count{}; // Word counter |
| 72 | for (const auto& word : list) |
| 73 | { |
| 74 | if (count++ % perline == 0 && count != 1) |
| 75 | std::cout << std::endl; |
| 76 | std::cout << word << ' '; |
| 77 | } |
| 78 | std::cout << std::endl; |
| 79 | } |
| 80 | } |