From 95bc0ffdb2f82f32aee77ef0de8f0d9b3633cf4e Mon Sep 17 00:00:00 2001 From: Night Cruising <77157236+night-cruise@users.noreply.github.com> Date: Thu, 31 Aug 2023 02:36:06 +0800 Subject: [PATCH] Feat: add rust codes for chapter searching (#710) --- codes/rust/Cargo.toml | 5 ++ .../chapter_searching/binary_search_edge.rs | 51 +++++++++++++++ .../binary_search_insertion.rs | 62 +++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 codes/rust/chapter_searching/binary_search_edge.rs create mode 100644 codes/rust/chapter_searching/binary_search_insertion.rs diff --git a/codes/rust/Cargo.toml b/codes/rust/Cargo.toml index 1b311391f..c2978fde0 100644 --- a/codes/rust/Cargo.toml +++ b/codes/rust/Cargo.toml @@ -114,6 +114,11 @@ path = "chapter_searching/binary_search.rs" name = "binary_search_edge" path = "chapter_searching/binary_search_edge.rs" +# Run Command: cargo run --bin binary_search_insertion +[[bin]] +name = "binary_search_insertion" +path = "chapter_searching/binary_search_insertion.rs" + # Run Command: cargo run --bin bubble_sort [[bin]] name = "bubble_sort" diff --git a/codes/rust/chapter_searching/binary_search_edge.rs b/codes/rust/chapter_searching/binary_search_edge.rs new file mode 100644 index 000000000..e5baede9f --- /dev/null +++ b/codes/rust/chapter_searching/binary_search_edge.rs @@ -0,0 +1,51 @@ +/* + * File: binary_search_edge.rs + * Created Time: 2023-08-30 + * Author: night-cruise (2586447362@qq.com) + */ + +mod binary_search_insertion; + +use binary_search_insertion::binary_search_insertion; + + +/* 二分查找最左一个 target */ +fn binary_search_left_edge(nums: &[i32], target: i32) -> i32 { + // 等价于查找 target 的插入点 + let i = binary_search_insertion(nums, target); + // 未找到 target ,返回 -1 + if i == nums.len() as i32 || nums[i as usize] != target { + return -1; + } + // 找到 target ,返回索引 i + i +} + +/* 二分查找最右一个 target */ +fn binary_search_right_edge(nums: &[i32], target: i32) -> i32 { + // 转化为查找最左一个 target + 1 + let i = binary_search_insertion(nums, target + 1); + // j 指向最右一个 target ,i 指向首个大于 target 的元素 + let j = i - 1; + // 未找到 target ,返回 -1 + if j == -1 || nums[j as usize] != target { + return -1; + } + // 找到 target ,返回索引 j + j +} + +/* Driver Code */ +fn main() { + // 包含重复元素的数组 + let nums = [1, 3, 6, 6, 6, 6, 6, 10, 12, 15]; + println!("\n数组 nums = {:?}", nums); + + // 二分查找左边界和右边界 + for target in [6, 7] { + let index = binary_search_left_edge(&nums, target); + println!("最左一个元素 {} 的索引为 {}", target, index); + let index = binary_search_right_edge(&nums, target); + println!("最右一个元素 {} 的索引为 {}", target, index); + } +} \ No newline at end of file diff --git a/codes/rust/chapter_searching/binary_search_insertion.rs b/codes/rust/chapter_searching/binary_search_insertion.rs new file mode 100644 index 000000000..654b63f42 --- /dev/null +++ b/codes/rust/chapter_searching/binary_search_insertion.rs @@ -0,0 +1,62 @@ +/* + * File: binary_search_insertion.rs + * Created Time: 2023-08-30 + * Author: night-cruise (2586447362@qq.com) + */ +#![allow(unused)] + +/* 二分查找插入点(无重复元素) */ +fn binary_search_insertion_simple(nums: &[i32], target: i32) -> i32 { + let (mut i, mut j) = (0, nums.len() as i32 - 1); // 初始化双闭区间 [0, n-1] + while i <= j { + let m = i + (j - i) / 2; // 计算中点索引 m + if nums[m as usize] < target { + i = m + 1; // target 在区间 [m+1, j] 中 + } else if nums[m as usize] > target { + j = m - 1; // target 在区间 [i, m-1] 中 + } else { + return m; + } + } + // 未找到 target ,返回插入点 i + i +} + +/* 二分查找插入点(存在重复元素) */ +pub fn binary_search_insertion(nums: &[i32], target: i32) -> i32 { + let (mut i, mut j) = (0, nums.len() as i32 - 1); // 初始化双闭区间 [0, n-1] + while i <= j { + let m = i + (j - i) / 2; // 计算中点索引 m + if nums[m as usize] < target { + i = m + 1; // target 在区间 [m+1, j] 中 + } else if nums[m as usize] > target { + j = m - 1; // target 在区间 [i, m-1] 中 + } else { + j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中 + } + } + // 返回插入点 i + i +} + + +/* Driver Code */ +fn main() { + // 无重复元素的数组 + let nums = [1, 3, 6, 8, 12, 15, 23, 26, 31, 35]; + println!("\n数组 nums = {:?}", nums); + // 二分查找插入点 + for target in [6, 9] { + let index = binary_search_insertion_simple(&nums, target); + println!("元素 {} 的插入点的索引为 {}", target, index); + } + + // 包含重复元素的数组 + let nums = [1, 3, 6, 6, 6, 6, 6, 10, 12, 15]; + println!("\n数组 nums = {:?}", nums); + // 二分查找插入点 + for target in [2, 6, 20] { + let index = binary_search_insertion(&nums, target); + println!("元素 {} 的插入点的索引为 {}", target, index); + } +} \ No newline at end of file