arrays - 向下转换数组长度和索引

标签 arrays types casting rust

我正在实现二进制搜索。该函数在数组中找到目标值时返回目标值的索引,否则返回-1

我更喜欢处理 i32 而不是 usize 的索引,因为当目标是未找到。我明确地在函数的边缘进行转换,我认为这不是很好。什么是更 Rusty 的解决方法?

fn binary_search(nums: &[i32], target: i32) -> i32 {
    let num_size: i32 = nums.len() as i32;            // This seems bad
    bsearch(nums, target, 0, num_size as usize)
}

fn bsearch(nums: &[i32], target: i32, lo: usize, hi: usize) -> i32 {
    if hi < lo {
        return -1;
    }

    let mid_idx = lo + ((hi - lo) / 2);
    let guess = nums[mid_idx];

    if guess > target {
        bsearch(nums, target, lo, mid_idx - 1)
    } else if guess < target {
        bsearch(nums, target, mid_idx + 1, hi)
    } else {
        mid_idx as i32                      // This seems bad
    }
}

最佳答案

您不必要地与语言作斗争。 i32 不是数组索引的合适类型。相反,您应该使用 Option:

fn binary_search(nums: &[i32], target: i32) -> Option<usize> {
    let num_size = nums.len();
    bsearch(nums, target, 0, num_size)
}

fn bsearch(nums: &[i32], target: i32, lo: usize, hi: usize) -> Option<usize> {
    if hi < lo {
        return None;
    }

    let mid_idx = lo + ((hi - lo) / 2);
    let guess = nums[mid_idx];

    if guess > target {
        bsearch(nums, target, lo, mid_idx - 1)
    } else if guess < target {
        bsearch(nums, target, mid_idx + 1, hi)
    } else {
        Some(mid_idx)
    }
}

鉴于处理数组的函数必须对索引使用usize,强制它使用i32 没有任何好处。如果你想要i32因为你希望“not found”为-1,你可以在函数完成后执行转换。


注意:另外,请记住,在使用 i32 时,您确实应该进行边界检查。在 64 位系统上,数组长度可能大大超过 i32 可以表示的长度,即使在 32 位机器上,您也面临数组索引为负数的风险。

关于arrays - 向下转换数组长度和索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41930702/

相关文章:

c# - 运算符 '??' 不能应用于类型 'System.Guid?' 和 'string' 的操作数

arrays - 如何检查数组中的所有值是否相同?

c - 在邻接表中使用 DFS 并使用指针的指针数组

c - 打印二维数组的内容(指针的指针)

c++ - 将一组内存从 void* 转换为一个类

python - 将 Cython 中的 C 结构包装/转换为 Python 类

arrays - Fortran 指针数组

mysql - 关于连接 int 类型和 varchar 类型的 2 列时的索引

java - 在 Java 中组合泛型类型

尽管进行了彻底检查,但在 Modelsim 上的仿真中类型不匹配的 VHDL 代码