Rust 标准库提供了Vec
Vec
Vec
fn main() {
// 创建空向量
let mut numbers: Vec = Vec::new();
// 使用宏创建并初始化向量
let mut names = vec!["Alice", "Bob", "Carol"];
// 向量添加元素
numbers.push(1);
numbers.push(2);
numbers.push(3);
numbers.pop(); // 移除并返回最后一个元素
// 访问向量中的元素
if let Some(first_name) = names.get(0) {
println!("第一个名字是:{}", first_name);
}
// 遍历向量元素
for name in &names {
println!("{}", name);
}
// 修改向量中的元素
if let Some(first_name) = names.get_mut(0) {
*first_name = "Dave";
}
// 使用迭代器处理向量元素
let numbers_squared: Vec = numbers.iter().map(|&x| x * x).collect();
println!("平方数:{:?}", numbers_squared);
// 用额外元素扩展向量
numbers.extend([4, 5, 6].iter().copied());
// 直接使用索引访问元素
println!("第二个名字:{}", names[1]); // 注意:直接索引可能引发恐慌
}
向量适用于处理相同类型的元素序列,无论是字符串、整数还是自定义类型。
HashMap
HashMap
use std::collections::HashMap;
fn main() {
// 创建空哈希表
let mut book_reviews: HashMap = HashMap::new();
// 向哈希表中添加元素
book_reviews.insert("The Hobbit".to_string(), "优秀的奇幻书籍".to_string());
book_reviews.insert("The Catcher in the Rye".to_string(), "经典小说".to_string());
// 访问哈希表中的元素
if let Some(review) = book_reviews.get("The Hobbit") {
println!("《霍比特人》的评论:{}", review);
}
// 从哈希表中移除元素
book_reviews.remove("The Catcher in the Rye");
// 遍历哈希表
for (book, review) in &book_reviews {
println!("{}: {}", book, review);
}
// 更新哈希表中的元素
book_reviews.entry("The Hobbit".to_string()).or_insert("未找到评论".to_string());
book_reviews.entry("1984".to_string()).or_insert("反乌托邦科幻小说".to_string());
let mut scores = HashMap::new();
// 使用 `insert` 直接插入
scores.insert("Blue", 10);
scores.insert("Blue", 25); // 覆盖之前的值
// 使用 `entry` 更新或插入
scores.entry("Yellow").or_insert(50); // 插入,因为 "Yellow" 不存在
scores.entry("Blue").or_insert(50); // 无操作,因为 "Blue" 已存在
// 结果:{"Blue": 25, "Yellow": 50}
// 检查键是否存在
if book_reviews.contains_key("1984") {
println!("1984 的评论可用。");
}
}
HashSet
HashSet
use std::collections::HashSet;
fn main() {
// 创建空集合
let mut numbers = HashSet::new();
// 向集合中添加元素
numbers.insert(1);
numbers.insert(2);
numbers.insert(3);
// 从集合中移除元素
numbers.remove(&3);
// 检查元素是否存在于集合中
if numbers.contains(&1) {
println!("1 在集合中");
}
// 遍历集合
for number in &numbers {
println!("{}", number);
}
// 集合操作:并集、交集、差集、对称差集
// 此时,numbers 包含 {1, 2}
let other_numbers = [2, 3, 4].iter().cloned().collect::<HashSet<_>>();
// other_numbers 包含 {2, 3, 4}
let union = numbers.union(&other_numbers).cloned().collect::<HashSet<_>>();
println!("并集:{:?}", union);
// 并集:`{1, 2, 3, 4}`(两个集合中的所有唯一元素)
let intersection = numbers.intersection(&other_numbers).cloned().collect::<HashSet<_>>();
println!("交集:{:?}", intersection);
// 交集:`{2}`(共同元素)
let difference = numbers.difference(&other_numbers).cloned().collect::<HashSet<_>>();
println!("差集:{:?}", difference);
// 差集:`{1}`(在 `numbers` 中但不在 `other_numbers` 中的元素)
let symmetric_difference = numbers.symmetric_difference(&other_numbers).cloned().collect::<HashSet<_>>();
println!("对称差集:{:?}", symmetric_difference);
// 对称差集:`{1, 3, 4}`(每个集合中唯一的元素)
}
双向链表(LinkedList)
LinkedList
use std::collections::LinkedList;
fn main() {
// 创建新的空链表
let mut list: LinkedList = LinkedList::new();
// 向列表尾部添加元素
list.push_back(1);
list.push_back(2);
// 向列表头部添加元素
list.push_front(0);
// 从列表头部和尾部弹出元素
assert_eq!(list.pop_front(), Some(0));
assert_eq!(list.pop_back(), Some(2));
// 遍历列表
for elem in list.iter() {
println!("{}", elem);
}
// 修改列表中的元素(需要使用迭代器)
let mut iter_mut = list.iter_mut();
if let Some(first_elem) = iter_mut.next() {
*first_elem = 3;
}
// 打印修改后的列表
println!("修改后的列表:{:?}", list);
}
当需要频繁在列表开头或结尾处添加或删除元素时,LinkedList 是不错的选择,因为这些操作的时间复杂度为 O(1)。
如果应用程序很少需要随机访问,那么链表比向量更合适。
BTreeMap
BTreeMap
use std::collections::BTreeMap;
fn main() {
// 创建新的空 BTreeMap
let mut map: BTreeMap = BTreeMap::new();
// 向 BTreeMap 中插入键值对
map.insert("apple".to_string(), 3);
map.insert("banana".to_string(), 2);
map.insert("pear".to_string(), 4);
// 获取对应键的值
if let Some(v) = map.get("apple") {
println!("apple: {}", v);
}
// 移除键值对
map.remove("banana");
// 遍历 BTreeMap
for (key, value) in &map {
println!("{}: {}", key, value);
}
// 范围查询:获取 "apple" 和 "pear"(含)之间所有键值对
let range = map.range("apple".to_string()..="pear".to_string());
for (key, value) in range {
println!("范围查询:{}: {}", key, value);
}
}
当需要自动排序时,BTreeMap 是不错的选择。
如果程序频繁进行有序的查找、插入和删除操作,BTreeMap 可能比 HashMap 更合适,因为它保持键的顺序,便于有序遍历。
B 树集(BTreeSet)
BTreeSet
use std::collections::BTreeSet;
fn main() {
// 创建新的空 BTreeSet
let mut set: BTreeSet = BTreeSet::new();
// 向集合中添加元素
set.insert(12);
set.insert(5);
set.insert(18);
// 检查元素是否存在
if set.contains(&12) {
println!("集合包含 12");
}
// 移除元素
set.remove(&5);
// 遍历集合(元素将按升序排列)
for num in &set {
println!("{}", num);
}
// 范围查询:获取大于等于 10 且小于 20 的所有元素
for num in set.range(10..20) {
println!("范围查询:{}", num);
}
}
当需要有序集合进行快速查找、范围查询或有序遍历时,BTreeSet 是不错的选择。
BinaryHeap
BinaryHeap
use std::collections::BinaryHeap;
fn main() {
// 创建新的空 BinaryHeap
let mut heap = BinaryHeap::new();
// 向堆中添加元素
heap.push(1);
heap.push(5);
heap.push(2);
// 查看堆中的最大元素而不移除它
if let Some(max) = heap.peek() {
println!("最大元素:{}", max);
}
// 移除并返回最大元素
println!("移除的最大元素:{}", heap.pop().unwrap());
// 遍历堆(迭代顺序未排序)
for num in &heap {
println!("{}", num);
}
}
当需要快速访问和移除最大(或最小)元素时,BinaryHeap 理想选择。这在 Dijkstra 最短路径等算法中尤为有用。
BinaryHeap 适用于任务调度、贪心算法或任何需要优先队列的场景。
原文:
https://dev.to/leapcell/from-vectors-to-hashsets-navigating-rusts-data-structures-1p7a