You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求重构Rust代码:优化最大序列乘积与错误处理实现

没问题!咱们来重构这段Rust代码,让它更高效、优雅,并且完全用链式迭代器实现lsp函数。先看看原代码可以优化的地方:两次遍历字符串检查无效字符+转换数字、冗余的sp函数、unwrap()可能引发panic,还有滑动窗口乘积计算可以更紧凑。

下面是重构后的代码,我会逐段解释优化点:

#[derive(Debug, PartialEq)]
pub enum Error {
    SpanTooLong,
    InvalidDigit(char),
}

pub fn lsp(string_digits: &str, span: usize) -> Result<u64, Error> {
    // 先处理边界情况:span为0或空字符串直接返回1
    if span == 0 || string_digits.is_empty() {
        return Ok(1);
    }

    // 一次遍历完成:字符转u8数字+无效字符错误处理
    let digits = string_digits
        .chars()
        .map(|c| {
            c.to_digit(10)
                .map(|d| d as u8)
                .ok_or_else(|| Error::InvalidDigit(c))
        })
        .collect::<Result<Vec<u8>, Error>>()?;

    // 检查span是否超出字符串长度
    if span > digits.len() {
        return Err(Error::SpanTooLong);
    }

    // 链式迭代器完成滑动窗口乘积计算+找最大值
    digits
        .windows(span)
        // 优化:如果窗口包含0,直接返回0,避免多余乘法计算
        .map(|window| {
            if window.contains(&0) {
                0
            } else {
                window.iter().fold(1u64, |acc, &d| acc * u64::from(d))
            }
        })
        .max()
        // 理论上不会走到这里,因为前面已经确保span <= digits.len()
        .ok_or(Error::SpanTooLong)
}

核心优化点:

  • 合并遍历与错误处理:原代码先遍历一次收集无效字符,再遍历一次转数字,现在用map结合ok_or_else,一次遍历完成转换和错误检查,减少了一次O(n)遍历。
  • 移除冗余函数:把sp函数的逻辑直接内联到迭代器的map中,代码更紧凑直观。
  • 避免panic风险:原代码中ch.to_digit(10).unwrap()和.unwrap()都可能引发panic,现在所有潜在错误都通过Result处理,更安全。
  • 链式迭代器风格:从digits.windows(span)开始,用map计算乘积、max找最大值,整个流程完全链式调用,符合Rust的函数式编程风格。
  • 乘积计算优化:提前检查窗口中的0,直接返回0,避免不必要的乘法运算,尤其是当span较大时能提升效率。

测试验证

比如输入lsp("1234", 2),会返回Ok(12)(3*4);输入lsp("abc", 2)会返回Err(Error::InvalidDigit('a'));输入lsp("12", 3)会返回Err(Error::SpanTooLong),和原代码的行为完全一致,但更高效优雅。

内容的提问来源于stack exchange,提问作者Ahmed Tawfeeq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:29:05