From f55039411e3cdd46d3cf6db9521eafeedf77a884 Mon Sep 17 00:00:00 2001 From: Reality Enjoyer Date: Fri, 16 Jan 2026 07:20:40 +0000 Subject: [PATCH] improve solution to second exercise - create new function to search substrings - update PROGRESS.md --- PROGRESS.md | 5 +- exercises/string-manipulator/src/main.rs | 58 +++++++++++++++++------- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index 533872e..9586d0d 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -37,6 +37,7 @@ - [ ] Wallet Module Structure (crypto) ### Milestone 5: Chapters 8-9 (Collections, Error Handling) +- [x] Vec Statistics Calculator (Vec, HashMap, basic math) - 2026-01-15 - [ ] Contact Manager (HashMap, Option, Result) - [ ] Log Parser (Vec, filtering, file handling) - [ ] Transaction Pool/Mempool (crypto) @@ -58,7 +59,9 @@ - [ ] Async HTTP, JSON parsing ## 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* \ No newline at end of file diff --git a/exercises/string-manipulator/src/main.rs b/exercises/string-manipulator/src/main.rs index ca37b2d..d235d01 100644 --- a/exercises/string-manipulator/src/main.rs +++ b/exercises/string-manipulator/src/main.rs @@ -1,25 +1,31 @@ -use std::collections::HashMap; - fn main() { let mut test = StringTool::new(); test.add_string("hello".to_string()); test.add_string("world".to_string()); + test.add_string("learning rust is fun!".to_string()); test.add_string("rust programming".to_string()); 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); println!( - "DEBUG: string(s) with {word} are:\n\t{:?}", + "\nDEBUG: string(s) with \"{word}\" are:\n\t{:?}", 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!"); - println!("{longest}"); + println!("\nDEBUG: the longest string is: \"{longest}\""); test.to_uppercase_all(); - println!("{:?}", test); + println!("\nDEBUG: everything uppercase \n\t{:?}", test); } #[derive(Debug)] @@ -39,19 +45,17 @@ impl StringTool { } fn longest(&self) -> Option<&str> { - if self.collection.len() < 1 { + if self.collection.is_empty() { return None; } else { let mut longest_string = &self.collection[0]; let mut length = longest_string.len(); - let mut count = 0; for v in &self.collection { if v.len() > length { longest_string = v; length = longest_string.len(); } - count += 1; } Some(longest_string.as_str()) } @@ -61,7 +65,7 @@ impl StringTool { *v = v.to_uppercase(); } } - //TODO improve search + fn contains_word(&self, word: &str) -> Vec<&str> { let collection = &self.collection; let mut return_val: Vec<&str> = Vec::new(); @@ -71,8 +75,6 @@ impl StringTool { let words: Vec<_> = v.split_ascii_whitespace().collect(); //for words in string for w in words { - // for characters in word - if w == word { return_val.push(v); } @@ -80,8 +82,32 @@ impl StringTool { } 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 { -// // counts total occurences of each word -// }