|
| 1 | +--- |
| 2 | +minutes: 20 |
| 3 | +--- |
| 4 | + |
| 5 | +# Exercise: Word Counter |
| 6 | + |
| 7 | +Create a program that counts the frequency of words in a given text. The program should: |
| 8 | + |
| 9 | +1. Take a string of text as input |
| 10 | +2. Split the text into words (consider words to be separated by whitespace) |
| 11 | +3. Count how many times each word appears (case-insensitive) |
| 12 | +4. Print the words and their counts in alphabetical order |
| 13 | + |
| 14 | +Use a `HashMap` to store the word counts. |
| 15 | + |
| 16 | +## Example |
| 17 | + |
| 18 | +```rust |
| 19 | +fn main() { |
| 20 | + let text = "the quick brown fox jumps over the lazy dog"; |
| 21 | + let counts = count_words(text); |
| 22 | + print_word_counts(&counts); |
| 23 | +} |
| 24 | +``` |
| 25 | + |
| 26 | +Expected output: |
| 27 | +``` |
| 28 | +brown: 1 |
| 29 | +dog: 1 |
| 30 | +fox: 1 |
| 31 | +jumps: 1 |
| 32 | +lazy: 1 |
| 33 | +over: 1 |
| 34 | +quick: 1 |
| 35 | +the: 2 |
| 36 | +``` |
| 37 | + |
| 38 | +## Tasks |
| 39 | + |
| 40 | +1. Implement the `count_words` function that takes a string slice and returns a `HashMap<String, u32>` |
| 41 | +2. Make the word counting case-insensitive (e.g., "The" and "the" count as the same word) |
| 42 | +3. Implement the `print_word_counts` function that prints the word counts in alphabetical order |
| 43 | +4. Add tests for: |
| 44 | + - Empty input |
| 45 | + - Simple text with repeated words |
| 46 | + - Case-insensitive counting |
| 47 | + |
| 48 | +## Extension Tasks (Optional) |
| 49 | + |
| 50 | +1. Add support for reading text from a file |
| 51 | +2. Add statistics like total words, unique words, and average word length |
| 52 | +3. Find and display the most common words |
| 53 | + |
| 54 | +[View solution](word_counter_solution.md) |
| 55 | + |
| 56 | +```rust,editable |
| 57 | +use std::collections::HashMap; |
| 58 | +
|
| 59 | +/// WordCounter counts the frequency of words in text. |
| 60 | +struct WordCounter { |
| 61 | + word_counts: HashMap<String, usize>, |
| 62 | +} |
| 63 | +
|
| 64 | +impl WordCounter { |
| 65 | + /// Create a new WordCounter. |
| 66 | + fn new() -> Self { |
| 67 | + todo!("Initialize the WordCounter") |
| 68 | + } |
| 69 | +
|
| 70 | + /// Count words in the given text. |
| 71 | + fn count_words(&mut self, text: &str) { |
| 72 | + todo!("Implement word counting logic") |
| 73 | + } |
| 74 | +
|
| 75 | + /// Get the count for a specific word. |
| 76 | + fn word_count(&self, word: &str) -> usize { |
| 77 | + todo!("Return the count for the given word") |
| 78 | + } |
| 79 | +
|
| 80 | + /// Find the most frequent word(s) and their count. |
| 81 | + fn most_frequent(&self) -> Vec<(&str, usize)> { |
| 82 | + todo!("Find and return the most frequent word(s)") |
| 83 | + } |
| 84 | +} |
| 85 | +
|
| 86 | +#[test] |
| 87 | +fn test_word_counter() { |
| 88 | + let mut counter = WordCounter::new(); |
| 89 | + counter.count_words("Hello world, hello Rust!"); |
| 90 | + assert_eq!(counter.word_count("hello"), 2); |
| 91 | + assert_eq!(counter.word_count("rust"), 1); |
| 92 | + assert_eq!(counter.word_count("world"), 1); |
| 93 | +} |
0 commit comments