From e0ec5f25c1eaa0b4e87a3458329b2c802180f446 Mon Sep 17 00:00:00 2001 From: sunface Date: Mon, 7 Mar 2022 22:13:12 +0800 Subject: [PATCH] add Vector.md --- solutions/collections/Hashmap.md | 209 ++++++++++++++++++++++++++ solutions/collections/Vector.md | 0 src/SUMMARY.md | 4 +- src/collections/vector.md | 243 +++++++++++++++++++++++++++++++ 4 files changed, 454 insertions(+), 2 deletions(-) create mode 100644 solutions/collections/Hashmap.md create mode 100644 solutions/collections/Vector.md diff --git a/solutions/collections/Hashmap.md b/solutions/collections/Hashmap.md new file mode 100644 index 0000000..60f4f86 --- /dev/null +++ b/solutions/collections/Hashmap.md @@ -0,0 +1,209 @@ +1. +```rust +fn main() { + let arr: [u8; 3] = [1, 2, 3]; + + let v = Vec::from(arr); + is_vec(&v); + + let v = vec![1, 2, 3]; + is_vec(&v); + + // vec!(..) and vec![..] are same macros, so + let v = vec!(1, 2, 3); + is_vec(&v); + + // in code below, v is Vec<[u8; 3]> , not Vec + // USE `for` to rewrite the below code + let mut v1 = Vec::new(); + for i in &v { + v1.push(*i) + } + is_vec(&v1); + + assert_eq!(format!("{:?}",v), format!("{:?}",v1)); + + println!("Success!") +} + +fn is_vec(v: &Vec) {} +``` + +2. +```rust +fn main() { + let mut v1 = Vec::from([1, 2, 4]); + v1.pop(); + v1.push(3); + + let mut v2 = Vec::new(); + v2.extend([1, 2, 3]); + + assert_eq!(format!("{:?}",v1), format!("{:?}",v2)); + + println!("Success!") +} +``` + +3. +```rust +fn main() { + // array -> Vec + let arr = [1, 2, 3]; + let v1 = Vec::from(arr); + let v2: Vec = arr.into(); + + assert_eq!(v1, v2); + + + // String -> Vec + let s = "hello".to_string(); + let v1: Vec = s.into(); + + let s = "hello".to_string(); + let v2 = s.into_bytes(); + assert_eq!(v1, v2); + + let s = "hello"; + let v3 = Vec::from(s); + assert_eq!(v2, v3); + + println!("Success!") + } + ``` + +4. +```rust,editable +fn main() { + let mut v = Vec::from([1, 2, 3]); + for i in 0..5 { + println!("{:?}", v.get(i)) + } + + for i in 0..5 { + if let Some(x) = v.get(i) { + v[i] = x + 1 + } else { + v.push(i + 2) + } + } + + assert_eq!(format!("{:?}",v), format!("{:?}", vec![2, 3, 4, 5, 6])); + + println!("Success!") +} +``` + +5. +```rust +// FIX the errors +fn main() { + let mut v = vec![1, 2, 3]; + + let slice1 = &v[..]; + // out of bounds will cause a panic + // You must use `v.len` here + let slice2 = &v[0..v.len()]; + + assert_eq!(slice1, slice2); + + // slice are read only + // Note: slice and &Vec are different + let vec_ref: &mut Vec = &mut v; + (*vec_ref).push(4); + let slice3 = &mut v[0..]; + + assert_eq!(slice3, &[1, 2, 3, 4]); + + println!("Success!") +} +``` + +6. +```rust +// FIX the errors +fn main() { + let mut vec = Vec::with_capacity(10); + + // The vector contains no items, even though it has capacity for more + assert_eq!(vec.len(), 0); + assert_eq!(vec.capacity(), 10); + + // These are all done without reallocating... + for i in 0..10 { + vec.push(i); + } + assert_eq!(vec.len(), 10); + assert_eq!(vec.capacity(), 10); + + // ...but this may make the vector reallocate + vec.push(11); + assert_eq!(vec.len(), 11); + assert!(vec.capacity() >= 11); + + + // fill in an appropriate value to make the `for` done without reallocating + let mut vec = Vec::with_capacity(100); + for i in 0..100 { + vec.push(i); + } + + assert_eq!(vec.len(), 100); + assert_eq!(vec.capacity(), 100); + + println!("Success!") +} +``` + +7. +```rust +#[derive(Debug, PartialEq)] +enum IpAddr { + V4(String), + V6(String), +} +fn main() { + // FILL in the blank + let v : Vec= vec![ + IpAddr::V4("127.0.0.1".to_string()), + IpAddr::V6("::1".to_string()) + ]; + + // Comparing two enums need to derive the PartialEq trait + assert_eq!(v[0], IpAddr::V4("127.0.0.1".to_string())); + assert_eq!(v[1], IpAddr::V6("::1".to_string())); + + println!("Success!") +} +``` + +8. +```rust +trait IpAddr { + fn display(&self); +} + +struct V4(String); +impl IpAddr for V4 { + fn display(&self) { + println!("ipv4: {:?}",self.0) + } +} +struct V6(String); +impl IpAddr for V6 { + fn display(&self) { + println!("ipv6: {:?}",self.0) + } +} + +fn main() { + let v: Vec> = vec![ + Box::new(V4("127.0.0.1".to_string())), + Box::new(V6("::1".to_string())), + ]; + + for ip in v { + ip.display(); + } +} +``` \ No newline at end of file diff --git a/solutions/collections/Vector.md b/solutions/collections/Vector.md new file mode 100644 index 0000000..e69de29 diff --git a/src/SUMMARY.md b/src/SUMMARY.md index f40dbc4..a74e301 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -30,8 +30,8 @@ - [Advanced Traits](generics-traits/advanced-traits.md) - [Collection Types](collections/intro.md) - [String](collections/string.md) - - [Vector todo](collections/vector.md) - - [HashMap todo](collections/hashmap.md) + - [Vector](collections/vector.md) + - [HashMap](collections/hashmap.md) - [Type Conversion todo](type-conversion.md) - [Result and panic todo](result-panic/intro.md) - [panic!](result-panic/panic.md) diff --git a/src/collections/vector.md b/src/collections/vector.md index a2303c1..aed6588 100644 --- a/src/collections/vector.md +++ b/src/collections/vector.md @@ -1 +1,244 @@ # Vector +Vectors are re-sizable arrays. Like slices, their size is not known at compile time, but they can grow or shrink at any time. + +### Basic Operations +1. 🌟🌟🌟 +```rust,editable + +fn main() { + let arr: [u8; 3] = [1, 2, 3]; + + let v = Vec::from(arr); + is_vec(v); + + let v = vec![1, 2, 3]; + is_vec(v); + + // vec!(..) and vec![..] are same macros, so + let v = vec!(1, 2, 3); + is_vec(v); + + // in code below, v is Vec<[u8; 3]> , not Vec + // USE Vec::new and `for` to rewrite the below code + let v1 = vec!(arr); + is_vec(v1); + + assert_eq!(v, v1); + + println!("Success!") +} + +fn is_vec(v: Vec) {} +``` + + + +2. 🌟🌟 a Vec can be extended with `extend` method +```rust,editable + +// FILL in the blank +fn main() { + let mut v1 = Vec::from([1, 2, 4]); + v1.pop(); + v1.push(3); + + let mut v2 = Vec::new(); + v2.__; + + assert_eq!(v1, v2); + + println!("Success!") +} +``` + +### Turn X Into Vec +3. 🌟🌟🌟 +```rust,editable + +// FILL in the blanks +fn main() { + // array -> Vec + // impl From<[T; N]> for Vec + let arr = [1, 2, 3]; + let v1 = __(arr); + let v2: Vec = arr.__(); + + assert_eq!(v1, v2); + + + // String -> Vec + // impl From for Vec + let s = "hello".to_string(); + let v1: Vec = s.__(); + + let s = "hello".to_string(); + let v2 = s.into_bytes(); + assert_eq!(v1, v2); + + // impl<'_> From<&'_ str> for Vec + let s = "hello"; + let v3 = Vec::__(s); + assert_eq!(v2, v3); + + // Iterators can be collected into vectors + let v4: Vec = [0; 10].into_iter().collect(); + assert_eq!(v4, vec![0; 10]); + + println!("Success!") + } +``` + +### Indexing +4. 🌟🌟🌟 +```rust,editable + +// FIX the error and IMPLEMENT the code +fn main() { + let mut v = Vec::from([1, 2, 3]); + for i in 0..5 { + println!("{:?}", v[i]) + } + + for i in 0..5 { + // IMPLEMENT the code here... + } + + assert_eq!(v, vec![2, 3, 4, 5, 6]); + + println!("Success!") +} +``` + + +### Slicing +A Vec can be mutable. On the other hand, slices are read-only objects. To get a slice, use `&`. + +In Rust, it’s more common to pass slices as arguments rather than vectors when you just want to provide read access. The same goes for `String` and `&str`. + +5. 🌟🌟 +```rust,editable + +// FIX the errors +fn main() { + let mut v = vec![1, 2, 3]; + + let slice1 = &v[..]; + // out of bounds will cause a panic + // You must use `v.len` here + let slice2 = &v[0..4]; + + assert_eq!(slice1, slice2); + + // slice are read only + // Note: slice and &Vec are different + let vec_ref: &mut Vec = &mut v; + (*vec_ref).push(4); + let slice3 = &mut v[0..3]; + slice3.push(4); + + assert_eq!(slice3, &[1, 2, 3, 4]); + + println!("Success!") +} +``` +### Capacity +The capacity of a vector is the amount of space allocated for any future elements that will be added onto the vector. This is not to be confused with the length of a vector, which specifies the number of actual elements within the vector. If a vector’s length exceeds its capacity, its capacity will automatically be increased, but its elements will have to be reallocated. + +For example, a vector with capacity 10 and length 0 would be an empty vector with space for 10 more elements. Pushing 10 or fewer elements onto the vector will not change its capacity or cause reallocation to occur. However, if the vector’s length is increased to 11, it will have to reallocate, which can be slow. For this reason, it is recommended to use `Vec::with_capacity `whenever possible to specify how big the vector is expected to get. + +6. 🌟🌟 +```rust,editable +// FIX the errors +fn main() { + let mut vec = Vec::with_capacity(10); + + // The vector contains no items, even though it has capacity for more + assert_eq!(vec.len(), __); + assert_eq!(vec.capacity(), 10); + + // These are all done without reallocating... + for i in 0..10 { + vec.push(i); + } + assert_eq!(vec.len(), __); + assert_eq!(vec.capacity(), __); + + // ...but this may make the vector reallocate + vec.push(11); + assert_eq!(vec.len(), 11); + assert!(vec.capacity() >= 11); + + + // fill in an appropriate value to make the `for` done without reallocating + let mut vec = Vec::with_capacity(__); + for i in 0..100 { + vec.push(i); + } + + assert_eq!(vec.len(), __); + assert_eq!(vec.capacity(), __); + + println!("Success!") +} +``` + +### Store distinct types in Vector +The elements in a vector mush be the same type, for example , the code below will cause an error: +```rust +fn main() { + let v = vec![1, 2.0, 3]; +} +``` + +But we can use enums or trait objects to store distinct types. + +7. 🌟🌟 +```rust,editable +#[derive(Debug)] +enum IpAddr { + V4(String), + V6(String), +} +fn main() { + // FILL in the blank + let v : Vec= __; + + // Comparing two enums need to derive the PartialEq trait + assert_eq!(v[0], IpAddr::V4("127.0.0.1".to_string())); + assert_eq!(v[1], IpAddr::V6("::1".to_string())); + + println!("Success!") +} +``` + +8. 🌟🌟 +```rust,editable +trait IpAddr { + fn display(&self); +} + +struct V4(String); +impl IpAddr for V4 { + fn display(&self) { + println!("ipv4: {:?}",self.0) + } +} +struct V6(String); +impl IpAddr for V6 { + fn display(&self) { + println!("ipv6: {:?}",self.0) + } +} + +fn main() { + // FILL in the blank + let v: __= vec![ + Box::new(V4("127.0.0.1".to_string())), + Box::new(V6("::1".to_string())), + ]; + + for ip in v { + ip.display(); + } +} +``` \ No newline at end of file