练习:计数器

在本练习中,您将学习一个非常简单的数据结构,并将其变成泛型的。该结构使用 std::collections::HashMap 来跟踪已经出现过的值以及每个值出现的次数。

Counter 的初始版本经过硬编码,仅适用于 u32 值。使结构体及其方法可用于所跟踪的值类型,以便 Counter 能够跟踪任何类型的值。

如果提前完成操作,请尝试使用 entry 方法将哈希查找次数减半,从而实现 count 方法。

1. use std::collections::HashMap;

3. /// Counter counts the number of times each value of type T has been seen.
4. struct Counter {
5. values: HashMap<u32, u64>,
6. }

8. impl Counter {
9. /// Create a new Counter.
10. fn new() -> Self {
11. Counter {
12. values: HashMap::new(),
13. }
14. }

16. /// Count an occurrence of the given value.
17. fn count(&mut self, value: u32) {
18. if self.values.contains_key(&value) {
19. *self.values.get_mut(&value).unwrap() += 1;
20. } else {
21. self.values.insert(value, 1);
22. }
23. }

25. /// Return the number of times the given value has been seen.
26. fn times_seen(&self, value: u32) -> u64 {
27. self.values.get(&value).copied().unwrap_or_default()
28. }
29. }

31. fn main() {
32. let mut ctr = Counter::new();
33. ctr.count(13);
34. ctr.count(14);
35. ctr.count(16);
36. ctr.count(14);
37. ctr.count(14);
38. ctr.count(11);

40. for i in 10..20 {
41. println!("saw {} values equal to {}", ctr.times_seen(i), i);
42. }

44. let mut strctr = Counter::new();
45. strctr.count("apple");
46. strctr.count("orange");
47. strctr.count("apple");
48. println!("got {} apples", strctr.times_seen("apple"));
49. }