Skip to content

Commit 718577c

Browse files
author
Your Name
committed
Add word counter exercise and solution
1 parent 5211436 commit 718577c

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed

src/std-types/word_counter.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
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+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use std::collections::HashMap;
2+
3+
/// Count the frequency of words in a text.
4+
/// Returns a HashMap with words as keys and their counts as values.
5+
fn count_words(text: &str) -> HashMap<String, u32> {
6+
let mut word_counts = HashMap::new();
7+
8+
for word in text.split_whitespace() {
9+
let word = word.to_lowercase();
10+
*word_counts.entry(word).or_insert(0) += 1;
11+
}
12+
13+
word_counts
14+
}
15+
16+
/// Print word counts in alphabetical order
17+
fn print_word_counts(counts: &HashMap<String, u32>) {
18+
let mut words: Vec<_> = counts.keys().collect();
19+
words.sort();
20+
21+
for word in words {
22+
println!("{}: {}", word, counts[word]);
23+
}
24+
}
25+
26+
#[test]
27+
fn test_empty_string() {
28+
let counts = count_words("");
29+
assert!(counts.is_empty());
30+
}
31+
32+
#[test]
33+
fn test_simple_text() {
34+
let counts = count_words("the quick brown fox jumps over the lazy dog");
35+
assert_eq!(counts["the"], 2);
36+
assert_eq!(counts["fox"], 1);
37+
assert_eq!(counts.len(), 8);
38+
}
39+
40+
#[test]
41+
fn test_case_insensitive() {
42+
let counts = count_words("The THE the");
43+
assert_eq!(counts["the"], 3);
44+
}
45+
46+
fn main() {
47+
let text = "the quick brown fox jumps over the lazy dog";
48+
let counts = count_words(text);
49+
print_word_counts(&counts);
50+
}

0 commit comments

Comments
 (0)