Rust - Bộ sưu tập

Thư viện thu thập tiêu chuẩn của Rust cung cấp các triển khai hiệu quả của các cấu trúc dữ liệu lập trình mục đích chung phổ biến nhất. Chương này thảo luận về việc triển khai các tập hợp thường được sử dụng - Vector, HashMap và HashSet.

Véc tơ

Vector là một mảng có thể thay đổi kích thước. Nó lưu trữ các giá trị trong các khối bộ nhớ liền nhau. Cấu trúc được xác định trước Vec có thể được sử dụng để tạo vectơ. Một số tính năng quan trọng của Vector là:

  • Một Vector có thể phát triển hoặc thu nhỏ trong thời gian chạy.

  • Vector là một tập hợp đồng nhất.

  • Một Vector lưu trữ dữ liệu dưới dạng chuỗi các phần tử theo một thứ tự cụ thể. Mỗi phần tử trong một Vectơ được gán một số chỉ mục duy nhất. Chỉ mục bắt đầu từ 0 và tăng lên n-1 trong đó, n là kích thước của tập hợp. Ví dụ, trong tập hợp 5 phần tử, phần tử đầu tiên sẽ ở chỉ số 0 và phần tử cuối cùng sẽ ở chỉ số 4.

  • Một Vectơ sẽ chỉ nối các giá trị vào (hoặc gần) cuối. Nói cách khác, một Vector có thể được sử dụng để triển khai một ngăn xếp.

  • Bộ nhớ cho một Vector được cấp phát trong heap.

Cú pháp - Tạo một vectơ

let mut instance_name = Vec::new();

Phương thức tĩnh new () của cấu trúc Vec được sử dụng để tạo một thể hiện vectơ.

Ngoài ra, một vector cũng có thể được tạo bằng vec! vĩ mô. Cú pháp như sau:

let vector_name = vec![val1,val2,val3]

Bảng sau liệt kê một số hàm thường được sử dụng của cấu trúc Vec.

Sr.No phương pháp Chữ ký & Mô tả
1 Mới()

pub fn new()->Vect

Tạo một Vec mới, trống. Vectơ sẽ không phân bổ cho đến khi các phần tử được đẩy lên nó.

2 đẩy()

pub fn push(&mut self, value: T)

Thêm một phần tử vào phía sau một tập hợp.

3 tẩy()

pub fn remove(&mut self, index: usize) -> T

Loại bỏ và trả về phần tử tại chỉ mục vị trí trong vectơ, dịch chuyển tất cả các phần tử sau nó sang trái.

4 chứa đựng()

pub fn contains(&self, x: &T) -> bool

Trả về true nếu lát chứa phần tử có giá trị đã cho.

5 len ()

pub fn len(&self) -> usize

Trả về số phần tử trong vectơ, còn được gọi là 'độ dài' của nó.

Minh họa: Tạo Vector - new ()

Để tạo một vector, chúng tôi sử dụng phương thức static new -

fn main() {
   let mut v = Vec::new();
   v.push(20);
   v.push(30);
   v.push(40);

   println!("size of vector is :{}",v.len());
   println!("{:?}",v);
}

Ví dụ trên tạo một Vector bằng phương thức tĩnh new () được định nghĩa trong cấu trúc Vec . Hàm push (val) thêm giá trị được truyền dưới dạng tham số vào bộ sưu tập. Hàm len () trả về độ dài của vectơ.

Đầu ra

size of vector is :3
[20, 30, 40]

Hình minh họa: Tạo một Vector - vec! Macro

Đoạn mã sau tạo một vectơ bằng vec! vĩ mô. Kiểu dữ liệu của vectơ được suy ra là giá trị đầu tiên được gán cho nó.

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

Đầu ra

[1, 2, 3]

Như đã đề cập trước đó, một vectơ chỉ có thể chứa các giá trị của cùng một kiểu dữ liệu. Đoạn mã sau sẽ gây ra lỗi [E0308]: lỗi loại không khớp .

fn main() {
   let v = vec![1,2,3,"hello"];
   println!("{:?}",v);
}

Minh họa: push ()

Thêm một phần tử vào cuối tập hợp.

fn main() {
   let mut v = Vec::new();
   v.push(20);
   v.push(30);
   v.push(40);
   
   println!("{:?}",v);
}

Đầu ra

[20, 30, 40]

Hình minh họa: remove ()

Loại bỏ và trả về phần tử tại chỉ mục vị trí trong vectơ, dịch chuyển tất cả các phần tử sau nó sang trái.

fn main() {
   let mut v = vec![10,20,30];
   v.remove(1);
   println!("{:?}",v);
}

Đầu ra

[10, 30]

Hình minh họa - chứa ()

Trả về true nếu lát chứa phần tử có giá trị đã cho -

fn main() {
   let v = vec![10,20,30];
   if v.contains(&10) {
      println!("found 10");
   }
   println!("{:?}",v);
}

Đầu ra

found 10
[10, 20, 30]

Hình minh họa: len ()

Trả về số phần tử trong vectơ, còn được gọi là 'độ dài' của nó.

fn main() {
   let v = vec![1,2,3];
   println!("size of vector is :{}",v.len());
}

Đầu ra

size of vector is :3

Truy cập các giá trị từ một Vectơ

Các phần tử riêng lẻ trong một vectơ có thể được truy cập bằng cách sử dụng số chỉ mục tương ứng của chúng. Ví dụ sau tạo một quảng cáo vectơ in giá trị của phần tử đầu tiên.

fn main() {
   let mut v = Vec::new();
   v.push(20);
   v.push(30);

   println!("{:?}",v[0]);
}
Output: `20`

Các giá trị trong một vectơ cũng có thể được tìm nạp bằng cách sử dụng tham chiếu đến bộ sưu tập.

fn main() {
   let mut v = Vec::new();
   v.push(20);
   v.push(30);
   v.push(40);
   v.push(500);

   for i in &v {
      println!("{}",i);
   }
   println!("{:?}",v);
}

Đầu ra

20
30
40
500
[20, 30, 40, 500]

Bản đồ băm

Bản đồ là một tập hợp các cặp khóa-giá trị (được gọi là các mục nhập). Không có hai mục nào trong một bản đồ có thể có cùng một khóa. Tóm lại, bản đồ là một bảng tra cứu. HashMap lưu trữ các khóa và giá trị trong bảng băm. Các mục nhập được lưu trữ theo thứ tự tùy ý. Khóa được sử dụng để tìm kiếm các giá trị trong HashMap. Cấu trúc HashMap được định nghĩa trongstd::collectionsmô-đun. Mô-đun này phải được nhập rõ ràng để truy cập cấu trúc HashMap.

Cú pháp: Tạo HashMap

let mut instance_name = HashMap::new();

Phương thức tĩnh new () của cấu trúc HashMap được sử dụng để tạo một đối tượng HashMap. Phương pháp này tạo ra một HashMap trống.

Các chức năng thường được sử dụng của HashMap được thảo luận dưới đây:

Sr.No phương pháp Chữ ký & Mô tả
1 chèn()

pub fn insert(&mut self, k: K, v: V) -> Option

Chèn một cặp khóa / giá trị, nếu không có khóa thì trả về Không có. Sau khi cập nhật, giá trị cũ được trả lại.

2 len ()

pub fn len(&self) -> usize

Trả về số phần tử trong bản đồ.

3 được()

pub fn get<Q: ?Sized>(&lself, k: &Q) -> Option<&V> where K:Borrow Q:Hash+ Eq

Trả về một tham chiếu đến giá trị tương ứng với khóa.

4 iter ()

pub fn iter(&self) -> Iter<K, V>

Một trình lặp truy cập tất cả các cặp khóa-giá trị theo thứ tự tùy ý. Loại phần tử của trình lặp là (& 'a K, &' a V).

5 khóa_ chứa

pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool

Trả về true nếu bản đồ chứa giá trị cho khóa được chỉ định.

6 tẩy()

pub fn remove_entry<Q: ?Sized>(&mut self, k: &Q) -> Option<(K, V)>

Xóa khóa khỏi bản đồ, trả lại khóa và giá trị đã lưu trữ nếu khóa trước đó có trong bản đồ.

Hình minh họa: insert ()

Chèn một cặp khóa / giá trị vào HashMap.

use std::collections::HashMap;
fn main(){
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   println!("{:?}",stateCodes);
}

Chương trình trên tạo một HashMap và khởi tạo nó với 2 cặp khóa-giá trị.

Đầu ra

{"KL": "Kerala", "MH": "Maharashtra"}

Hình minh họa: len ()

Trả về số phần tử trong bản đồ

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   println!("size of map is {}",stateCodes.len());
}

Ví dụ trên tạo HashMap và in ra tổng số phần tử trong đó.

Đầu ra

size of map is 2

Hình minh họa - get ()

Trả về một tham chiếu đến giá trị tương ứng với khóa. Ví dụ sau lấy giá trị cho khóa KL trong HashMap.

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   println!("size of map is {}",stateCodes.len());
   println!("{:?}",stateCodes);

   match stateCodes.get(&"KL") {
      Some(value)=> {
         println!("Value for key KL is {}",value);
      }
      None => {
         println!("nothing found");
      }
   }
}

Đầu ra

size of map is 2
{"KL": "Kerala", "MH": "Maharashtra"}
Value for key KL is Kerala

Hình minh họa - iter ()

Trả về một trình lặp có chứa tham chiếu đến tất cả các cặp khóa-giá trị theo thứ tự tùy ý.

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");

   for (key, val) in stateCodes.iter() {
      println!("key: {} val: {}", key, val);
   }
}

Đầu ra

key: MH val: Maharashtra
key: KL val: Kerala

Hình minh họa: contains_key ()

Trả về true nếu bản đồ chứa giá trị cho khóa được chỉ định.

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   stateCodes.insert("GJ","Gujarat");

   if stateCodes.contains_key(&"GJ") {
      println!("found key");
   }
}

Đầu ra

found key

Hình minh họa: remove ()

Xóa khóa khỏi bản đồ.

use std::collections::HashMap;
fn main() {
   let mut stateCodes = HashMap::new();
   stateCodes.insert("KL","Kerala");
   stateCodes.insert("MH","Maharashtra");
   stateCodes.insert("GJ","Gujarat");

   println!("length of the hashmap {}",stateCodes.len());
   stateCodes.remove(&"GJ");
   println!("length of the hashmap after remove() {}",stateCodes.len());
}

Đầu ra

length of the hashmap 3
length of the hashmap after remove() 2

HashSet

HashSet là một tập hợp các giá trị duy nhất của loại T. Việc thêm và xóa các giá trị rất nhanh, và nhanh chóng để hỏi liệu một giá trị đã cho có nằm trong tập hợp đó hay không. Cấu trúc HashSet được định nghĩa trong mô-đun std :: collection. Mô-đun này phải được nhập rõ ràng để truy cập cấu trúc HashSet.

Cú pháp: Tạo HashSet

let mut hash_set_name = HashSet::new();

Phương thức tĩnh, mới , của cấu trúc HashSet được sử dụng để tạo một HashSet. Phương thức này tạo một HashSet trống.

Bảng sau liệt kê một số phương thức thường được sử dụng của cấu trúc HashSet.

Sr.No phương pháp Chữ ký & Mô tả
1 chèn()

pub fn insert(&mut self, value: T) -> bool

Thêm một giá trị vào tập hợp. Nếu tập hợp không có giá trị này, true được trả về ngược lại false.

2 len ()

pub fn len(&self) -> usize

Trả về số phần tử trong tập hợp.

3 được()

pub fn get<Q:?Sized>(&self, value: &Q) -> Option<&T> where T: Borrow,Q: Hash + Eq,

Trả về một tham chiếu đến giá trị trong tập hợp, nếu có thì bằng giá trị đã cho.

4 iter ()

pub fn iter(&self) -> Iter

Trả về một trình lặp truy cập tất cả các phần tử theo thứ tự tùy ý. Loại phần tử của trình lặp là & 'a T.

5 khóa_ chứa

pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool

Trả về true nếu tập hợp chứa một giá trị.

6 tẩy()

pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool

Xóa một giá trị khỏi tập hợp. Trả về true nếu giá trị có trong tập hợp.

Hình minh họa - insert ()

Thêm một giá trị vào tập hợp. HashSet không thêm các giá trị trùng lặp vào tập hợp.

use std::collections::HashSet;
fn main() {
   let mut names = HashSet::new();

   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   names.insert("Mohtashim");//duplicates not added

   println!("{:?}",names);
}

Đầu ra

{"TutorialsPoint", "Kannan", "Mohtashim"}

Hình minh họa: len ()

Trả về số phần tử trong tập hợp.

use std::collections::HashSet;
fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   println!("size of the set is {}",names.len());
}

Đầu ra

size of the set is 3

Hình minh họa - iter ()

Truy xuất một trình lặp truy cập tất cả các phần tử theo thứ tự tùy ý.

use std::collections::HashSet;
fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   names.insert("Mohtashim");

   for name in names.iter() {
      println!("{}",name);
   }
}

Đầu ra

TutorialsPoint
Mohtashim
Kannan

Hình minh họa: get ()

Trả về một tham chiếu đến giá trị trong tập hợp, nếu có, bằng giá trị đã cho.

use std::collections::HashSet;
fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   names.insert("Mohtashim");

   match names.get(&"Mohtashim"){
      Some(value)=>{
         println!("found {}",value);
      }
      None =>{
         println!("not found");
      }
   }
   println!("{:?}",names);
}

Đầu ra

found Mohtashim
{"Kannan", "Mohtashim", "TutorialsPoint"}

Hình minh họa - chứa ()

Trả về true nếu tập hợp chứa một giá trị.

use std::collections::HashSet;

fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");

   if names.contains(&"Kannan") {
      println!("found name");
   }  
}

Đầu ra

found name

Hình minh họa: remove ()

Xóa một giá trị khỏi tập hợp.

use std::collections::HashSet;

fn main() {
   let mut names = HashSet::new();
   names.insert("Mohtashim");
   names.insert("Kannan");
   names.insert("TutorialsPoint");
   println!("length of the Hashset: {}",names.len());
   names.remove(&"Kannan");
   println!("length of the Hashset after remove() : {}",names.len());
}

Đầu ra

length of the Hashset: 3
length of the Hashset after remove() : 2