improve solution to second exercise

- create new function to search substrings
- update PROGRESS.md
This commit is contained in:
2026-01-16 07:20:40 +00:00
parent 0b910bf74d
commit f55039411e
2 changed files with 46 additions and 17 deletions

View File

@@ -37,6 +37,7 @@
- [ ] Wallet Module Structure (crypto) - [ ] Wallet Module Structure (crypto)
### Milestone 5: Chapters 8-9 (Collections, Error Handling) ### Milestone 5: Chapters 8-9 (Collections, Error Handling)
- [x] Vec Statistics Calculator (Vec, HashMap, basic math) - 2026-01-15
- [ ] Contact Manager (HashMap, Option, Result) - [ ] Contact Manager (HashMap, Option, Result)
- [ ] Log Parser (Vec, filtering, file handling) - [ ] Log Parser (Vec, filtering, file handling)
- [ ] Transaction Pool/Mempool (crypto) - [ ] Transaction Pool/Mempool (crypto)
@@ -58,7 +59,9 @@
- [ ] Async HTTP, JSON parsing - [ ] Async HTTP, JSON parsing
## Reflections ## Reflections
*Space for learning insights and "aha" moments*
### 2026-01-15 - Vec Statistics Exercise
**Key Learning:** Type conversion and ownership struggles are normal! Spent 45min wrestling with `usize` vs `i32` vs `f64` for vector length, and dealing with moved values when iterating multiple times. The compiler suggestions led to complex generics at first, but simpler `as f64` casting solved the type issues. HashMap frequency counting clicked once the ownership issues were resolved. **Insight:** "Terrible but working" code is a valid first step - iterate to clean it up.
--- ---
*This file tracks overall learning journey and milestone completion* *This file tracks overall learning journey and milestone completion*

View File

@@ -1,25 +1,31 @@
use std::collections::HashMap;
fn main() { fn main() {
let mut test = StringTool::new(); let mut test = StringTool::new();
test.add_string("hello".to_string()); test.add_string("hello".to_string());
test.add_string("world".to_string()); test.add_string("world".to_string());
test.add_string("learning rust is fun!".to_string());
test.add_string("rust programming".to_string()); test.add_string("rust programming".to_string());
println!("\nDEBUG: current values\n\t{:?}", test); println!("\nDEBUG: current values\n\t{:?}", test);
let word = "o".to_string(); let word = "rust".to_string();
let strings_with_word = test.contains_word(&word); let strings_with_word = test.contains_word(&word);
println!( println!(
"DEBUG: string(s) with {word} are:\n\t{:?}", "\nDEBUG: string(s) with \"{word}\" are:\n\t{:?}",
strings_with_word strings_with_word
); );
let seq = "st".to_string();
let strings_with_seq = test.contains_seq(&seq);
println!(
"\nDEBUG: string(s) with \"{seq}\" are:\n\t{:?}",
strings_with_seq
);
let longest = test.longest().unwrap_or("collection is empty!"); let longest = test.longest().unwrap_or("collection is empty!");
println!("{longest}"); println!("\nDEBUG: the longest string is: \"{longest}\"");
test.to_uppercase_all(); test.to_uppercase_all();
println!("{:?}", test); println!("\nDEBUG: everything uppercase \n\t{:?}", test);
} }
#[derive(Debug)] #[derive(Debug)]
@@ -39,19 +45,17 @@ impl StringTool {
} }
fn longest(&self) -> Option<&str> { fn longest(&self) -> Option<&str> {
if self.collection.len() < 1 { if self.collection.is_empty() {
return None; return None;
} else { } else {
let mut longest_string = &self.collection[0]; let mut longest_string = &self.collection[0];
let mut length = longest_string.len(); let mut length = longest_string.len();
let mut count = 0;
for v in &self.collection { for v in &self.collection {
if v.len() > length { if v.len() > length {
longest_string = v; longest_string = v;
length = longest_string.len(); length = longest_string.len();
} }
count += 1;
} }
Some(longest_string.as_str()) Some(longest_string.as_str())
} }
@@ -61,7 +65,7 @@ impl StringTool {
*v = v.to_uppercase(); *v = v.to_uppercase();
} }
} }
//TODO improve search
fn contains_word(&self, word: &str) -> Vec<&str> { fn contains_word(&self, word: &str) -> Vec<&str> {
let collection = &self.collection; let collection = &self.collection;
let mut return_val: Vec<&str> = Vec::new(); let mut return_val: Vec<&str> = Vec::new();
@@ -71,8 +75,6 @@ impl StringTool {
let words: Vec<_> = v.split_ascii_whitespace().collect(); let words: Vec<_> = v.split_ascii_whitespace().collect();
//for words in string //for words in string
for w in words { for w in words {
// for characters in word
if w == word { if w == word {
return_val.push(v); return_val.push(v);
} }
@@ -80,8 +82,32 @@ impl StringTool {
} }
return_val return_val
} }
fn contains_seq(&self, seq: &str) -> Vec<&str> {
let collection = &self.collection;
let mut result: Vec<&str> = Vec::new();
let len_seq = seq.len();
let mut iterations = 0;
for v in collection {
let string_len = v.len() as usize;
if string_len % len_seq == 0 {
iterations = string_len - 1 - (string_len % len_seq);
} else {
iterations = string_len - (string_len % len_seq);
}
if len_seq > string_len {
return result;
} else {
for i in 0..iterations {
let slice = v.get(i..i + len_seq).unwrap();
if seq == slice {
result.push(&v);
break;
}
}
continue;
}
}
result
}
} }
//
// fn word_count(&self) -> HashMap<String, usize> {
// // counts total occurences of each word
// }