當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


Rust BTreeMap用法及代碼示例

本文簡要介紹rust語言中 Struct std::collections::btree_map::BTreeMap 的用法。

用法

pub struct BTreeMap<K, V> { /* fields omitted */ }

基於 B-Tree 的Map。

B-Trees 代表了緩存效率和實際最小化搜索中執行的工作量之間的基本折衷。理論上,二叉搜索樹 (BST) 是排序圖的最佳選擇,因為完美平衡的 BST 執行查找元素所需的理論最小比較量 (log2n).然而,實際上這樣做的方式是非常對於現代計算機體係結構來說效率低下。特別是,每個元素都存儲在其自己的heap-allocated 節點中。這意味著每次插入都會觸發heap-allocation,並且每次比較都應該是緩存未命中。由於這些在實踐中都是非常昂貴的事情,我們被迫至少重新考慮 BST 策略。

相反,B-Tree 使每個節點在連續數組中包含 B-1 到 2B-1 個元素。通過這樣做,我們將分配次數減少了 B 倍,並提高了搜索時的緩存效率。然而,這確實意味著搜索必須進行更多的平均比較。精確的比較次數取決於所使用的節點搜索策略。為了獲得最佳緩存效率,可以線性搜索節點。為了獲得最佳比較,可以使用二分搜索來搜索節點。作為一種折衷方案,我們還可以執行線性搜索,最初僅檢查每個 ithi 的某些選擇的元素。

目前,我們的實現隻是簡單地執行簡單的線性搜索。這在比較便宜的元素的小節點上提供了出色的性能。然而,在未來,我們將進一步探索基於 B 的選擇以及可能的其他因子來選擇最優搜索策略。使用線性搜索,搜索隨機元素預計需要 B * log(n) 比較,這通常比 BST 差。然而,在實踐中,性能非常出色。

以這樣的方式修改鍵是一個邏輯錯誤,即鍵相對於任何其他鍵的順序(由 Ord 特征確定)在映射中時發生變化。這通常隻能通過 Cell RefCell 、全局狀態、I/O 或不安全代碼實現。未指定由此類邏輯錯誤導致的行為(它可能包括Panics、不正確的結果、中止、內存泄漏或未終止),但不會是未定義的行為。

例子

use std::collections::BTreeMap;

// type inference lets us omit an explicit type signature (which
// would be `BTreeMap<&str, &str>` in this example).
let mut movie_reviews = BTreeMap::new();

// review some movies.
movie_reviews.insert("Office Space",       "Deals with real issues in the workplace.");
movie_reviews.insert("Pulp Fiction",       "Masterpiece.");
movie_reviews.insert("The Godfather",      "Very enjoyable.");
movie_reviews.insert("The Blues Brothers", "Eye lyked it a lot.");

// check for a specific one.
if !movie_reviews.contains_key("Les Misérables") {
    println!("We've got {} reviews, but Les Misérables ain't one.",
             movie_reviews.len());
}

// oops, this review has a lot of spelling mistakes, let's delete it.
movie_reviews.remove("The Blues Brothers");

// look up the values associated with some keys.
let to_find = ["Up!", "Office Space"];
for movie in &to_find {
    match movie_reviews.get(movie) {
       Some(review) => println!("{}: {}", movie, review),
       None => println!("{} is unreviewed.", movie)
    }
}

// Look up the value for a key (will panic if the key is not found).
println!("Movie review: {}", movie_reviews["Office Space"]);

// iterate over everything.
for (movie, review) in &movie_reviews {
    println!("{}: \"{}\"", movie, review);
}

可以從數組初始化具有已知項目列表的BTreeMap

use std::collections::BTreeMap;

let solar_distance = BTreeMap::from([
    ("Mercury", 0.4),
    ("Venus", 0.7),
    ("Earth", 1.0),
    ("Mars", 1.5),
]);

BTreeMap 實現了一個 Entry API ,它允許獲取、設置、更新和刪除鍵及其值的複雜方法:

use std::collections::BTreeMap;

// type inference lets us omit an explicit type signature (which
// would be `BTreeMap<&str, u8>` in this example).
let mut player_stats = BTreeMap::new();

fn random_stat_buff() -> u8 {
    // could actually return some random value here - let's just return
    // some fixed value for now
    42
}

// insert a key only if it doesn't already exist
player_stats.entry("health").or_insert(100);

// insert a key using a function that provides a new value only if it
// doesn't already exist
player_stats.entry("defence").or_insert_with(random_stat_buff);

// update a key, guarding against the key possibly not being set
let stat = player_stats.entry("attack").or_insert(100);
*stat += random_stat_buff();

相關用法


注:本文由純淨天空篩選整理自rust-lang.org大神的英文原創作品 Struct std::collections::btree_map::BTreeMap。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。