欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Rust動態(tài)數(shù)組Vec基本概念及用法

 更新時間:2023年12月07日 15:25:18   作者:Hann Yang  
Rust中的Vec是一種動態(tài)數(shù)組,它可以在運行時自動調整大小,本文主要介紹了Rust動態(tài)數(shù)組Vec基本概念及用法,具有一定的參考價值,感興趣的可以了解一下

Rust中的Vec是一種動態(tài)數(shù)組,它可以在運行時自動調整大小。Vec是Rust標準庫的一部分,提供了一種高效、安全的方式來處理大量數(shù)據(jù)。基于堆內存申請的連續(xù)動態(tài)數(shù)據(jù)類型,其索引、壓入(push)、彈出(pop) 操作的時間復雜度為 O(1) 。

一、基本概念

Vec是什么?

Vec,是“vector”的縮寫。一種動態(tài)數(shù)組,它可以在運行時自動調整大小。Vec的底層實現(xiàn)是基于數(shù)組的,因此它的性能非常高。Vec可以存儲任何類型的數(shù)據(jù),包括整數(shù)、浮點數(shù)、字符串等。

Vec其實是一個智能指針,用于在上分配內存的動態(tài)數(shù)組。它提供了一些方法來操作數(shù)組,如添加、刪除和訪問元素。與C或Python中的數(shù)組不同,Vec會自動處理內存分配和釋放,從而避免了常見的內存泄漏和懸掛指針錯誤。

Vec的本質就是一個三元組,指針、長度、容量,在rust標準庫中的定義如下:

pub struct Vec<T, A: Allocator = Global> {
    buf: RawVec<T, A>,
    len: usize,
}
impl<T> Vec<T> {
    #[inline]
    pub const fn new() -> Self {
        Vec { buf: RawVec::NEW, len: 0 }
    }
//...略...
}

Vec的核心功能之一是動態(tài)增長和收縮。當向Vec中添加元素時,如果堆上的內存不足,Vec會自動分配更多的內存來容納元素。這個過程稱為“擴容”。同樣,當從Vec中刪除元素時,如果堆上的內存過多,Vec會自動收縮以釋放內存。這個過程稱為“縮容”。這種自動內存管理機制使得使用Vec變得非常方便,同時也避免了手動管理內存的錯誤。

除了基本的添加、刪除和訪問元素操作之外,Vec還提供了許多其他功能。例如,它們可以按索引訪問元素,可以使用迭代器遍歷元素,并且支持多種方法(如push()、pop()、insert()和remove())來修改Vec的內容。Vec還提供了一些有用的靜態(tài)方法(如capacity()、len()和is_empty()),可以用來獲取Vec的屬性。

雖然Vec是一個非常強大的數(shù)據(jù)結構,但它們也有一些限制。例如,Vec在堆上分配內存,這意味著訪問元素的速度可能會比在棧上分配內存的數(shù)組慢。此外,由于Vec是智能指針,因此它們的大小不是固定的,這可能會導致一些編程錯誤。例如,如果嘗試將Vec賦值給一個固定大小的數(shù)組或另一個Vec,則會發(fā)生編譯時錯誤。

Vec的特點

(1)動態(tài)大小:

Vec可以根據(jù)需要自動調整大小,無需預先分配內存。當元素數(shù)量發(fā)生變化時,Vec會自動重新分配內存并復制元素。

(2)可變性:

Vec是可變的,這意味著我們可以在不創(chuàng)建新Vec的情況下修改現(xiàn)有元素。這使得我們在處理大量數(shù)據(jù)時更加靈活。

(3)泛型:

Vec是泛型的,這意味著我們可以使用相同的方法來處理不同類型的數(shù)據(jù)。例如,我們可以使用vec![1, 2, 3]創(chuàng)建一個包含整數(shù)的Vec,使用vec!["a", "b", "c"]創(chuàng)建一個包含字符串的Vec。

動態(tài)數(shù)組是一種基于堆內存申請的連續(xù)動態(tài)數(shù)據(jù)類型,擁有 O(1) 時間復雜度的索引、壓入(push)、彈出(pop)。 

二、基礎用法

1. 創(chuàng)建

(1) Vec::new()方法

只創(chuàng)建一個空列表時,必須注明類型(否則通不過編譯)。如下例的正確用法:

fn main() {
    let vec: Vec<i32> = Vec::new();
    println!("{:?}", vec);
}

輸出:

[] 

注:print!、println!輸出Vec時需要使用格式符 "{:?}" 。

但如果下一步要添加元素,比如使用push(x)方法,就非必須注明類型,默認就是 i32 類型:

示例: 

fn main() {
    let mut vec = Vec::new();
    vec.push(1);
    vec.push(2);
    vec.push(3);
    println!("{:?}", vec);
}

輸出:

[1, 2, 3]

(2) Vec::from()方法

let vec = Vec::from([1,2,3]);

(3) vec! 宏

let vec = vec![1,2,3];

用法示例及判斷是否相等:

fn main() {
    let vec1 = Vec::from([1,2,3]);
    println!("{:?}", vec1);
    let vec2 = vec![1,2,3];
    println!("{:?}", vec2);
    assert_eq!(vec1, vec2);
    assert_eq!(vec1, [1,2,3]);
    assert_eq!(vec2, [1,2,3]);
    println!("{}", vec1 == vec2);
}

輸出:

[1, 2, 3]
[1, 2, 3]
true

vec! 宏 的另外用法: 

創(chuàng)建 len 個相同元素 n 的Vec,如:vec![n; len]。

示例:

fn main() {
    let vec = vec![0; 5];
    assert_eq!(vec, [0, 0, 0, 0, 0]);
    println!("{:?}", vec);
    let vec = vec![1; 3];
    assert_eq!(vec, [1, 1, 1]);
    println!("{:?}", vec);
    let vec = vec![1; 0];
}

以下是vec![1; 3]的等效方法,但速度較慢:

?fn main() {
    let mut vec = Vec::with_capacity(3);
    vec.resize(3, 1);
    assert_eq!(vec, [1, 1, 1]);
}

以上3種創(chuàng)建方法中,使用第3種方法的vec!宏來創(chuàng)建Vec相對比較方便。

二維Vec的創(chuàng)建和遍歷

fn main() {
    // 創(chuàng)建一個2x3的二維向量
    let matrix: Vec<Vec<i32>> = vec![
        vec![1, 2, 3], 
        vec![4, 5, 6]
    ];
    
    // 遍歷二維向量
    for row in &matrix {
        for &num in row {
            print!("{} ", num);
        }
        println!();
    }

    // 創(chuàng)建一個3x5的二維向量,所有元素都為 1
    let (m, n) = (3, 5);
    let number = 1;
    let matrix = vec![vec![number; n]; m];
    for row in &matrix {
        for &num in row {
            print!("{} ", num);
        }
        println!();
    }
}

輸出:

1 2 3 
4 5 6 
1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 

2. 基礎用法

Vec內置了非常豐富的內置方法,以下方法收集自網(wǎng)絡,有重復暫時沒空余時間去好好整理。

new(): 創(chuàng)建一個空的 Vec。
with_capacity(capacity: usize): 創(chuàng)建一個具有指定容量的空 Vec。
capacity() -> usize: 返回 Vec 的當前容量。
reserve(new_cap: usize): 為 Vec 分配額外的空間。
reserve_exact(new_cap: usize): 為 Vec 分配精確的額外空間。
shrink_to_fit(): 縮小 Vec 的容量以匹配其當前大小。
len() -> usize: 返回 Vec 的當前長度。
is_empty() -> bool: 檢查 Vec 是否為空。
push(value: T): 將一個值添加到 Vec 的末尾。
pop() -> Option<T>: 刪除并返回 Vec 的最后一個元素。
insert(index: usize, element: T): 在指定位置插入一個元素。
remove(index: usize) -> T: 刪除并返回指定位置的元素。
swap(index1: usize, index2: usize): 交換指定位置上的兩個元素。
truncate(len: usize): 將 Vec 截斷為指定長度。
clear(): 刪除 Vec 中的所有元素。
iter() -> Iter<T>: 返回一個迭代器,它允許按順序遍歷 Vec 中的元素。
iter_mut() -> IterMut<T>: 返回一個可變迭代器,它允許按順序遍歷 Vec 中的元素并進行修改。
into_iter() -> IntoIter<T>: 返回一個迭代器,它允許按順序遍歷 Vec 中的元素并轉移所有權。
split_off(at: usize) -> Vec<T>: 從指定位置將 Vec 拆分為兩個獨立的 Vec。
append(&mut self, other: &mut Vec<T>): 將另一個 Vec 的所有元素附加到當前 Vec 的末尾。

swap(index1: usize, index2: usize): 交換指定位置的兩個元素。
get(index: usize) -> Option<&T>: 獲取指定位置的元素的引用。
get_mut(index: usize) -> Option<&mut T>: 獲取指定位置的元素的可變引用。
first() -> Option<&T>: 獲取 Vec 的第一個元素的引用。
first_mut() -> Option<&mut T>: 獲取 Vec 的第一個元素的可變引用。
last() -> Option<&T>: 獲取 Vec 的最后一個元素的引用。
last_mut() -> Option<&mut T>: 獲取 Vec 的最后一個元素的可變引用。
split_at(index: usize) -> (&[T], &[T]): 將 Vec 分成兩個部分,從指定位置進行分割。
split_at_mut(index: usize) -> (&mut [T], &mut [T]): 將 Vec 分成兩個部分,從指定位置進行分割,返回可變引用。
as_slice() -> &[T]: 將 Vec 轉換為切片,返回不可變引用。
as_mut_slice() -> &mut [T]: 將 Vec 轉換為切片,返回可變引用。
iter() -> Iter<'_, T>: 返回一個迭代器,用于遍歷 Vec 中的元素。
iter_mut() -> IterMut<'_, T>: 返回一個迭代器,用于遍歷 Vec 中的元素,并返回可變引用。
into_iter() -> IntoIter<T>: 返回一個迭代器,用于遍歷 Vec 中的元素,Vec 在迭代過程中將被移動。
clone_from(other: &Vec<T>): 從另一個 Vec 復制元素到當前 Vec。
truncate(len: usize): 刪除 Vec 的尾部元素,直到長度為指定值。
clear(): 刪除 Vec 中的所有元素。

as_slice() -> &[T]: 將 Vec 轉換為不可變的切片。
as_mut_slice() -> &mut [T]: 將 Vec 轉換為可變的切片。
split_first() -> Option<(&T, &[T])>: 返回 Vec 的第一個元素和其余部分的元組。
split_first_mut() -> Option<(&mut T, &mut [T])>: 返回 Vec 的第一個元素和其余部分的可變引用。
split_last() -> Option<(&T, &[T])>: 返回 Vec 的最后一個元素和其余部分的元組。
split_last_mut() -> Option<(&mut T, &mut [T])>: 返回 Vec 的最后一個元素和其余部分的可變引用。
chunks(chunk_size: usize) -> Chunks<'_, T>: 返回一個迭代器,該迭代器按塊大小切分 Vec。
chunks_mut(chunk_size: usize) -> ChunksMut<'_, T>: 返回一個迭代器,該迭代器按塊大小切分 Vec,并返回可變引用。
windows(window_size: usize) -> Windows<'_, T>: 返回一個迭代器,該迭代器在 Vec 上滑動,返回指定大小的窗口。
iter() -> Iter<'_, T>: 返回一個不可變引用的迭代器,該迭代器遍歷 Vec 中的每個元素。
iter_mut() -> IterMut<'_, T>: 返回一個可變引用的迭代器,該迭代器遍歷 Vec 中的每個元素。
into_iter() -> IntoIter<T>: 返回一個擁有所有權的迭代器,該迭代器遍歷 Vec 中的每個元素。

chunks_exact(chunk_size: usize) -> ChunksExact<'_, T>: 返回一個迭代器,該迭代器按塊大小切分 Vec,每個塊都是固定大小的。
chunks_exact_mut(chunk_size: usize) -> ChunksExactMut<'_, T>: 返回一個迭代器,該迭代器按塊大小切分 Vec,每個塊都是固定大小的,并返回可變引用。
windows(window_size: usize) -> Windows<'_, T>: 返回一個迭代器,該迭代器按指定大小滑動窗口遍歷 Vec。
iter() -> Iter<'_, T>: 返回一個不可變的迭代器,遍歷 Vec 的元素。
iter_mut() -> IterMut<'_, T>: 返回一個可變的迭代器,遍歷 Vec 的元素并返回可變引用。
into_iter() -> IntoIter<T>: 返回一個將 Vec 轉換為迭代器的方法。
retain<F>(&mut self, f: F):在保留滿足給定謂詞的元素的情況下,刪除不滿足謂詞的所有元素。
dedup(&mut self):刪除連續(xù)重復的元素。只保留第一個出現(xiàn)的元素,其他的都被刪除。

retain<F>(&mut self, f: F):在保留滿足給定謂詞的元素的同時,移除不滿足謂詞的元素。
truncate(len: usize): 將 Vec 的長度截斷為指定長度。
dedup(): 移除 Vec 中相鄰的重復元素。
dedup_by_key<F>(&mut self, key: F):使用指定的鍵函數(shù),移除 Vec 中相鄰的具有相同鍵的元素。
clone_from(&self, source: &[T]): 從指定的 slice 復制元素到 Vec 中。
extend<I>(&mut self, iter: I):將迭代器中的元素添加到 Vec 的末尾。
extend_from_slice(slice: &[T]): 將 slice 中的元素添加到 Vec 的末尾。
resize(&mut self, new_len: usize, value: T):將 Vec 的長度更改為指定長度,并使用指定的值填充新元素。
resize_with<F>(&mut self, new_len: usize, f: F):將 Vec 的長度更改為指定長度,并使用指定的函數(shù)填充新元素。
swap_remove(index: usize) -> T:刪除并返回指定位置的元素,并用最后一個元素替換它。
truncate(len: usize): 將 Vec 的長度截斷為指定長度。

resize_with<F>(&mut self, new_len: usize, f: F):將 Vec 的長度更改為指定長度,并使用指定的函數(shù)生成新元素。
try_reserve(n: usize) -> Result<(), AllocError>:嘗試為至少包含指定數(shù)量的元素的 Vec 分配空間。
shrink_to_fit(): 縮小 Vec 的容量以匹配其當前長度。
as_ptr() -> *const T:返回 Vec 的指針。
as_mut_ptr() -> *mut T:返回 Vec 的可變指針。
capacity() -> usize:返回 Vec 的容量。
reserve(&mut self, additional: usize):為 Vec 分配額外的空間。
reserve_exact(&mut self, additional: usize):為 Vec 分配確切的額外空間。
set_len(&mut self, len: usize):設置 Vec 的長度,不檢查新長度是否小于或大于容量。
into_boxed_slice(self) -> Box<[T]>:將 Vec 轉換為包含所有元素的堆分配數(shù)組。
into_raw_parts(self) -> (*mut T, usize, usize):將 Vec 轉換為原始指針,長度和容量的三元組。

into_boxed_slice(self) -> Box<[T]>:將 Vec 轉換為包含所有元素的 Box<[T]>。
into_raw_parts(self) -> (*mut T, usize, usize):將 Vec 轉換為其原始指針、長度和容量的元組。
from_raw_parts(ptr: *mut T, len: usize, cap: usize) -> Vec<T>:從原始指針、長度和容量的元組創(chuàng)建 Vec。
from_raw_parts_mut(ptr: *mut T, len: usize, cap: usize) -> Vec<T>:從原始指針、長度和容量的元組創(chuàng)建可變的 Vec。
drain<R>(&mut self, range: R) -> Drain<'_, T>:刪除指定范圍內的元素,并返回一個迭代器,該迭代器遍歷已刪除的元素。

splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, R::End, I::IntoIter>:將指定范圍內的元素替換為迭代器中的元素,并返回一個迭代器,該迭代器遍歷已刪除的元素。
retain<F>(&mut self, f: F):在保留滿足給定謂詞的元素的同時,移除不滿足謂詞的元素。
partition<F>(&mut self, f: F) -> (Vec<T>, Vec<T>):根據(jù)給定謂詞,將 Vec 中的元素分成兩個新 Vec。
sort(&mut self):對 Vec 中的元素進行排序。
sort_by_key<K, F>(&mut self, key: F):使用指定的鍵函數(shù),對 Vec 中的元素進行排序。
sort_by<F>(&mut self, compare: F):使用指定的比較函數(shù),對 Vec 中的元素進行排序。
sort_unstable(): 對 Vec 中的元素進行不穩(wěn)定排序。
splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, R::End, I::IntoIter>:將指定范圍內的元素替換為迭代器中的元素,并返回一個迭代器,該迭代器遍歷已刪除的元素。
split_off(&mut self, at: usize) -> Vec<T>:將 Vec 拆分為兩個 Vec,從指定位置開始拆分。
swap_remove(&mut self, index: usize) -> T:刪除指定索引處的元素并返回它。
swap_remove_item(&mut self, item: &T) -> bool:查找并刪除第一個等于給定元素的元素,并返回是否找到該元素。
truncate(&mut self, len: usize):將 Vec 的長度截斷為指定長度。
unwrap():將包裝在 Option 中的 Vec 解包,如果是 None,則 panic。
unwrap_or(default: Vec<T>) -> Vec<T>:將包裝在 Option 中的 Vec 解包,如果是 None,則返回提供的默認值。
unwrap_or_default() -> Vec<T>:將包裝在 Option 中的 Vec 解包,如果是 None,則返回默認值。

unwrap_or(default: Vec<T>) -> Vec<T>:將包裝在 Option 中的 Vec 解包,如果是 None,則返回指定的默認值。
unwrap_or_else<F: FnOnce() -> Vec<T>>(f: F) -> Vec<T>:將包裝在 Option 中的 Vec 解包,如果是 None,則調用指定的函數(shù)生成默認值。
zip<U>(self, other: U) -> Zip<Self, U::IntoIter>:創(chuàng)建一個迭代器,該迭代器通過將 self 和其他迭代器的元素進行配對來生成元組。
iter() -> Iter<'_, T>:返回一個迭代器,該迭代器遍歷 Vec 的元素。
iter_mut() -> IterMut<'_, T>:返回一個可變迭代器,該迭代器遍歷 Vec 的元素。
into_iter(self) -> IntoIter<T>:將 Vec 轉換為其元素的迭代器。
len() -> usize:返回 Vec 的長度。
is_empty() -> bool:如果 Vec 為空,則返回 true,否則返回 false。
last() -> Option<&T>:返回 Vec 的最后一個元素的引用,如果 Vec 為空,則返回 None。
last_mut() -> Option<&mut T>:返回 Vec 的最后一個元素的可變引用,如果 Vec 為空,則返回 None。
split_first(&self) -> Option<(&T, &[T])>:返回 Vec 的第一個元素的引用和剩余元素的 slice,如果 Vec 為空,則返回 None。
split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>:返回 Vec 的第一個元素的可變引用和剩余元素的可變 slice,如果 Vec 為空,則返回 None。

is_empty() -> bool:如果 Vec 為空,則返回 true,否則返回 false。
as_slice(&self) -> &[T]:將 Vec 轉換為其元素的切片。
as_mut_slice(&mut self) -> &mut [T]:將 Vec 轉換為其元素的可變切片。
last(&self) -> Option<&T>:返回 Vec 的最后一個元素的引用,如果 Vec 為空,則返回 None。
last_mut(&mut self) -> Option<&mut T>:返回 Vec 的最后一個元素的可變引用,如果 Vec 為空,則返回 None。
first(&self) -> Option<&T>:返回 Vec 的第一個元素的引用,如果 Vec 為空,則返回 None。
first_mut(&mut self) -> Option<&mut T>:返回 Vec 的第一個元素的可變引用,如果 Vec 為空,則返回 None。
binary_search(&self, x: &T) -> Result<usize, usize>:在已排序的 Vec 中搜索指定元素,并返回其索引。
sort(&mut self):按升序對 Vec 的元素進行排序。
sort_by_key<K, F>(&mut self, f: F):按升序對 Vec 的元素進行排序,其中排序關鍵字由指定的函數(shù)生成。
sort_by<F>(&mut self, compare: F):按升序對 Vec 的元素進行排序,其中比較函數(shù)由指定的函數(shù)生成。

binary_search(&self, x: &T) -> Result<usize, usize>:在已排序的 Vec 中搜索指定元素,并返回它的索引。如果元素不存在,則返回 Err,該 Err 包含元素應該插入的位置的索引。
binary_search_by<F>(&self, f: F) -> Result<usize, usize> where F: FnMut(&T) -> Ordering:在已排序的 Vec 中使用指定的比較函數(shù)搜索指定元素,并返回它的索引。如果元素不存在,則返回 Err,該 Err 包含元素應該插入的位置的索引。
binary_search_by_key<K, F>(&self, key: &K, f: F) -> Result<usize, usize> where F: FnMut(&T) -> K, K: Ord:在已排序的 Vec 中使用指定的鍵函數(shù)搜索指定鍵,并返回它的索引。如果鍵不存在,則返回 Err,該 Err 包含鍵應該插入的位置的索引。
sort(&mut self):對 Vec 中的元素進行排序。
sort_by<F>(&mut self, compare: F):使用指定的比較函數(shù)對 Vec 中的元素進行排序。
sort_by_key<K, F>(&mut self, f: F):使用指定的鍵函數(shù)對 Vec 中的元素進行排序。
reverse(&mut self):反轉 Vec 中元素的順序。
split_off(&mut self, at: usize) -> Vec<T>:將 Vec 拆分為兩個 Vec,從指定位置開始拆分。

chunks(&self, chunk_size: usize) -> Chunks<'_, T>:返回一個迭代器,該迭代器遍歷 Vec 的不重疊的塊,每個塊包含指定數(shù)量的元素。
chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>:返回一個可變迭代器,該迭代器遍歷 Vec 的不重疊的塊,每個塊包含指定數(shù)量的元素。
windows(&self, window_size: usize) -> Windows<'_, T>:返回一個迭代器,該迭代器遍歷 Vec 的連續(xù)窗口,每個窗口包含指定數(shù)量的元素。
try_fold<B, F, R>(&self, init: B, f: F) -> R where F: FnMut(B, &T) -> Result<B, R>, R: From<B>:對 Vec 中的每個元素執(zhí)行指定的操作,并返回結果。如果任何操作返回 Err,則停止并返回 Err,否則返回 Ok。
try_for_each<F, R>(&self, f: F) -> R where F: FnMut(&T) -> Result<(), R>, R: From<()>:對 Vec 中的每個元素執(zhí)行指定的操作,并返回結果。如果任何操作返回 Err,則停止并返回 Err,否則返回 Ok。

try_for_each<F, R>(&self, f: F) -> R where F: FnMut(&T) -> Result<(), R>, R: From<()>:對 Vec 中的每個元素執(zhí)行指定的操作,并返回結果。如果任何操作返回 Err,則停止并返回 Err,否則返回 Ok。
contains(&self, x: &T) -> bool:如果 Vec 包含指定的元素,則返回 true,否則返回 false。
dedup(&mut self):刪除 Vec 中的重復元素。只保留第一次出現(xiàn)的元素。
dedup_by_key<F>(&mut self, key: F):刪除 Vec 中的重復元素。只保留第一次出現(xiàn)的元素。比較是使用指定的鍵函數(shù)進行的。
retain<F>(&mut self, f: F):從 Vec 中刪除不滿足指定條件的所有元素。
split_off(&mut self, at: usize) -> Vec<T>:從 Vec 中分離指定索引之后的所有元素,并返回一個新的 Vec。
truncate(&mut self, len: usize):將 Vec 的長度截斷為指定長度。如果指定長度小于 Vec 的當前長度,則刪除多余的元素。

三、Vec的簡單實現(xiàn)及其宏模擬

trait MyVec {
    type Item;
    fn new() -> Self;
    fn len(&self) -> usize;
    fn push(&mut self, element: Self::Item);
    fn pop(&mut self) -> Option<Self::Item>;
}

impl<T> MyVec for Vec<T> {
    type Item = T;

    fn new() -> Vec<T> {
        Vec::new()
    }

    fn len(&self) -> usize {
        Vec::len(self)
    }

    fn push(&mut self, element: T) {
        Vec::push(self, element)
    }
    
    fn pop(&mut self) -> Option<T> {
        Vec::pop(self)
    }
}

macro_rules! myvec {
    ( $( $x:expr ),* ) => {
        {
            let mut vec = <Vec<_> as MyVec>::new();
            $(
                vec.push($x);
            )*
            vec
        }
    };
}

fn main() {
    let mut v = myvec![1,2,3,4];
    println!("{:?}, size = {}", v, v.len());
    
    if let Some(last) = v.pop() {   // 檢查向量是否為空
        println!("彈出的尾部元素: {:?}", last);
        println!("{:?}, size = {}", v, v.len());
    } else {
        println!("Vector is empty");  // 向量為空的情況
    }

    v.push(5);
    println!("{:?}, size = {}", v, v.len());
}

輸出:

[1, 2, 3, 4], size = 4
彈出的尾部元素: 4
[1, 2, 3], size = 3
[1, 2, 3, 5], size = 4

四、leetcode 實戰(zhàn)

1. 長度最小的子數(shù)組 Minimum-size-subarray-sum

給定一個含有 n 個正整數(shù)的數(shù)組和一個正整數(shù) target 。

找出該數(shù)組中滿足其和 ≥ target 的長度最小的 連續(xù)子數(shù)組 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其長度。如果不存在符合條件的子數(shù)組,返回 0 。

示例 1:

輸入:target = 7, nums = [2,3,1,2,4,3]
輸出:2
解釋:子數(shù)組 [4,3] 是該條件下的長度最小的子數(shù)組。

示例 2:

輸入:target = 4, nums = [1,4,4]
輸出:1

提示:

1 <= target <= 10^9
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^5

代碼1:

fn min_sub_array_len(target: i32, nums: Vec<i32>) -> i32 {
    let mut i = 0;
    let mut j = 0;
    let mut sum = 0;
    let mut min_len = std::usize::MAX;
    while j < nums.len() {
        sum += nums[j];
        j += 1;
        while sum >= target {
            min_len = min_len.min(j - i);
            sum -= nums[i];
            i += 1;
        }
    }
    if min_len == std::usize::MAX {
        0
    } else {
        min_len as i32
    }
}

fn main() {
    let nums = vec![2, 3, 1, 2, 4, 3];
    println!("{}", min_sub_array_len(7, nums));
    let nums = vec![1, 4, 4];
    println!("{}", min_sub_array_len(4, nums));
}

代碼2:

fn min_sub_array_len(target: i32, nums: Vec<i32>) -> i32 {
    let mut min_len = i32::MAX;
    let (mut left, mut right) = (0, 0);
    let mut sum = 0;
    while right < nums.len() {
        sum += nums[right];
        while sum >= target {
            min_len = min(min_len, (right - left + 1) as i32);
            sum -= nums[left];
            left += 1;
        }
        right += 1;
    }
    if min_len == i32::MAX {
        return 0;
    }
    min_len
}
    
fn min(a: i32, b: i32) -> i32 {
    if a < b {
        a
    } else {
        b
    }
}

fn main() {
    let nums = vec![2, 3, 1, 2, 4, 3];
    println!("{}", min_sub_array_len(7, nums));
    let nums = vec![1, 4, 4];
    println!("{}", min_sub_array_len(4, nums));
}

2. 最大子數(shù)組和  Maximum Subarray

給你一個整數(shù)數(shù)組 nums ,請你找出一個具有最大和的連續(xù)子數(shù)組(子數(shù)組最少包含一個元素),返回其最大和。

子數(shù)組 是數(shù)組中的一個連續(xù)部分。

示例 1:

<strong>輸入:</strong>nums = [-2,1,-3,4,-1,2,1,-5,4]
<strong>輸出:</strong>6
<strong>解釋:</strong>連續(xù)子數(shù)組 [4,-1,2,1] 的和最大,為 6 。

示例 2:

<strong>輸入:</strong>nums = [1]
<strong>輸出:</strong>1

示例 3:

<strong>輸入:</strong>nums = [5,4,-1,7,8]
<strong>輸出:</strong>23

提示:

  • 1 <= nums.length <= 10^5
  • -10^4 <= nums[i] <= 10^4

進階:如果你已經實現(xiàn)復雜度為 O(n) 的解法,嘗試使用更為精妙的 分治法 求解。

代碼1: 動態(tài)規(guī)劃

fn max_sub_array(nums: &[i32]) -> i32 {
    let n = nums.len();
    let mut dp = vec![0; n];
    dp[0] = nums[0];
    for i in 1..n {
        dp[i] = std::cmp::max(dp[i-1] + nums[i], nums[i]);
    }
    let mut res = dp[0];
    for i in 1..n {
        res = std::cmp::max(res, dp[i]);
    }
    res
}

fn main() {
    let nums = vec![-2, 1, -3, 4, -1, 2, 1, -5, 4];
    println!("{}", max_sub_array(&nums));
    let nums = vec![1];
    println!("{}", max_sub_array(&nums));
    let nums = vec![5,4,-1,7,8];
    println!("{}", max_sub_array(&nums));
}

代碼2: 貪心算法

fn max_sub_array(nums: &[i32]) -> i32 {
    let n = nums.len();
    let (mut cur_sum, mut max_sum) = (0, nums[0]);
    for i in 0..n {
        cur_sum += nums[i];
        if cur_sum > max_sum {
            max_sum = cur_sum;
        }
        if cur_sum < 0 {
            cur_sum = 0;
        }
    }
    max_sum
}

fn main() {
    let nums = vec![-2, 1, -3, 4, -1, 2, 1, -5, 4];
    println!("{}", max_sub_array(&nums));
    let nums = vec![1];
    println!("{}", max_sub_array(&nums));
    let nums = vec![5,4,-1,7,8];
    println!("{}", max_sub_array(&nums));
}

輸出:

6
1
23

3. 螺旋矩陣 Spiral Matrix

給你一個 m 行 n 列的矩陣 matrix ,請按照 順時針螺旋順序 ,返回矩陣中的所有元素。

示例 1:

<strong>輸入:</strong>matrix = [[1,2,3],[4,5,6],[7,8,9]]
<strong>輸出:</strong>[1,2,3,6,9,8,7,4,5]

示例 2:

<strong>輸入:</strong>matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
<strong>輸出:</strong>[1,2,3,4,8,12,11,10,9,5,6,7]

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 10
  • -100 <= matrix[i][j] <= 100

代碼1:

fn spiral_order(matrix: &[Vec<i32>]) -> Vec<i32> {
    if matrix.is_empty() {
        return vec![];
    }
    let (m, n) = (matrix.len(), matrix[0].len());
    let mut res = vec![0; m * n];
    let (mut top, mut bottom, mut left, mut right) = (0, m - 1, 0, n - 1);
    let mut idx = 0;
    while top <= bottom && left <= right {
        for i in left..=right {
            res[idx] = matrix[top][i];
            idx += 1;
        }
        for i in top + 1..=bottom {
            res[idx] = matrix[i][right];
            idx += 1;
        }
        if top < bottom && left < right {
            for i in (left..right).rev() {
                res[idx] = matrix[bottom][i];
                idx += 1;
            }
            for i in (top + 1..=bottom - 1).rev() {
                res[idx] = matrix[i][left];
                idx += 1;
            }
        }
        top += 1;
        bottom -= 1;
        left += 1;
        right -= 1;
    }
    res
}

fn main() {
    let matrix = vec![
        vec![1, 2, 3],
        vec![4, 5, 6],
        vec![7, 8, 9],
    ];
    println!("{:?}", spiral_order(&matrix));
    let matrix = vec![
        vec![1, 2, 3, 4],
        vec![5, 6, 7, 8],
        vec![9,10,11,12],
    ];
    println!("{:?}", spiral_order(&matrix));
}

代碼2: 遞歸

fn spiral_order(matrix: Vec<Vec<i32>>) -> Vec<i32> {
    fn spiral_helper(top: usize, bottom: usize, left: usize, right: usize, res: &mut Vec<i32>, idx: &mut usize, matrix: &Vec<Vec<i32>>) {
        if top > bottom || left > right {
            return;
        }
        
        // 從左到右遍歷上邊界
        for i in left..=right {
            res[*idx] = matrix[top][i];
            *idx += 1;
        }
        
        // 從上到下遍歷右邊界
        for i in (top + 1)..=bottom {
            res[*idx] = matrix[i][right];
            *idx += 1;
        }
        
        if top < bottom && left < right {
            // 從右到左遍歷下邊界
            for i in (left..right).rev() {
                res[*idx] = matrix[bottom][i];
                *idx += 1;
            }
            
            // 從下到上遍歷左邊界
            for i in ((top + 1)..bottom).rev() {
                res[*idx] = matrix[i][left];
                *idx += 1;
            }
        }
        
        // 矩形邊界變小,遞歸調用spiral_helper繼續(xù)遍歷
        spiral_helper(top + 1, bottom - 1, left + 1, right - 1, res, idx, matrix);
        
    }
    
    let m = matrix.len();
    let n = matrix[0].len();
    let mut res = vec![0; m * n]; // 用于記錄遍歷結果
    let mut idx = 0; // 當前結果數(shù)組的下標
    
    // 從矩形最外層開始遍歷
    spiral_helper(0, m - 1, 0, n - 1, &mut res, &mut idx, &matrix);
    
    res
}

fn main() {
    let matrix = vec![
        vec![1, 2, 3],
        vec![4, 5, 6],
        vec![7, 8, 9],
    ];
    println!("{:?}", spiral_order(matrix));
    
    let matrix = vec![
        vec![1, 2, 3, 4],
        vec![5, 6, 7, 8],
        vec![9,10,11,12],
    ];
    println!("{:?}", spiral_order(matrix));
}

輸出:

[1, 2, 3, 6, 9, 8, 7, 4, 5]
[1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7] 

到此這篇關于Rust 動態(tài)數(shù)組Vec基本概念及用法的文章就介紹到這了,更多相關Rust 動態(tài)數(shù)組Vec內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Rust 累計時間長度的操作方法

    Rust 累計時間長度的操作方法

    在Rust中,如果你想要記錄累計時間,通??梢允褂脴藴蕩熘械膕td::time::Duration類型,這篇文章主要介紹了Rust如何累計時間長度,需要的朋友可以參考下
    2024-05-05
  • Rust 函數(shù)詳解

    Rust 函數(shù)詳解

    函數(shù)在 Rust 語言中是普遍存在的。Rust 支持多種編程范式,但更偏向于函數(shù)式,函數(shù)在 Rust 中是“一等公民”,函數(shù)可以作為數(shù)據(jù)在程序中進行傳遞,對Rust 函數(shù)相關知識感興趣的朋友一起看看吧
    2021-11-11
  • 如何使用VSCode配置Rust開發(fā)環(huán)境(Rust新手教程)

    如何使用VSCode配置Rust開發(fā)環(huán)境(Rust新手教程)

    這篇文章主要介紹了如何使用VSCode配置Rust開發(fā)環(huán)境(Rust新手教程),本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • 詳解Rust 生命周期符號使用的方法和規(guī)律

    詳解Rust 生命周期符號使用的方法和規(guī)律

    生命周期是 Rust 中處理引用和所有權的關鍵概念,通過正確使用生命周期符號和遵循相關規(guī)律,你可以編寫出安全、高效的 Rust 代碼,這篇文章主要介紹了Rust 生命周期符號使用的方法和規(guī)律,需要的朋友可以參考下
    2024-03-03
  • Rust 智能指針實現(xiàn)方法

    Rust 智能指針實現(xiàn)方法

    這篇文章主要介紹了Rust 智能指針的實現(xiàn)方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-01-01
  • Rust讀取配置文件的實現(xiàn)步驟

    Rust讀取配置文件的實現(xiàn)步驟

    任何項目都離不開對于配置文件的讀取和解析,rust項目也一樣,本文主要介紹了Rust讀取配置文件的實現(xiàn)步驟,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • Rust字符串類型全解析(最新推薦)

    Rust字符串類型全解析(最新推薦)

    Rust語言中,字符串類型眾多,設計初衷是為了確保程序的安全、高效和靈活性,本文詳細解釋了Rust中不同的字符串類型,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • 如何使用Rust的向量存儲值列表

    如何使用Rust的向量存儲值列表

    本文介紹了在Rust中使用向量存儲值列表的方法,包括創(chuàng)建、更新、讀取、遍歷、存儲多種類型以及內存釋放等方面,向量是Rust中常用且強大的集合類型,熟練掌握其用法有助于編寫高效且安全的代碼
    2025-02-02
  • Rust 文檔注釋功能示例代碼

    Rust 文檔注釋功能示例代碼

    Rust的文檔注釋使用特定的格式,以便通過 rustdoc工具生成 API 文檔,本文給大家介紹Rust 文檔注釋功能,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • Rust中的注釋使用解讀

    Rust中的注釋使用解讀

    本文介紹了Rust中的行注釋、塊注釋和文檔注釋的使用方法,通過示例展示了如何在實際代碼中應用這些注釋,以提高代碼的可讀性和可維護性
    2025-02-02

最新評論