【问题标题】:Canonical way to check for integer overflow in usize在 usize 中检查整数溢出的规范方法
【发布时间】:2021-10-04 18:01:45
【问题描述】:

我试图在 Rust 中解决以下leetcode problem

impl Solution {
    pub fn merge(nums1: &mut Vec<i32>, m: i32, nums2: &mut Vec<i32>, n: i32) {
        let mut backwards_idx: usize = (m + n - 1) as usize;
        let (m_size, n_size) = (m as usize, n as usize);
        let (mut m_idx, mut n_idx) = ((m-1) as usize, (n-1) as usize);
        while 0 <= m_idx && 0 <= n_idx {
            let (nums1_elem, nums2_elem) = (nums1[m_idx], nums2[n_idx]);
            if nums1_elem <= nums2_elem {
                nums1[backwards_idx] = nums2_elem;
                n_idx = n_idx - 1;
            } else {
                nums1[backwards_idx] = nums1_elem;
                m_idx = m_idx - 1;
            }
            backwards_idx = backwards_idx - 1;
        }
        while 0 <= m_idx {
            nums1[backwards_idx] = nums1[m_idx];
            m_idx = m_idx - 1;
            backwards_idx = backwards_idx - 1;
        }
        while 0 <= n_idx {
            nums1[backwards_idx] = nums2[n_idx];
            n_idx = n_idx - 1;
            backwards_idx = backwards_idx - 1;
        }
    }
}

但是,这是行不通的,因为m_sizen_size 在从 0 中减去时会溢出。我知道这不是规范的 Rust,但由于问题在 i32 中给出,我不能改变它。

checked method,但这似乎很难阅读,而不是在while循环条件下直接写它。不知何故,在 while 循环的主体中包含退出条件似乎不是一个好主意。

【问题讨论】:

  • 您引用的链接可能是问题重复的理由。但除此之外,您可以通过以不同方式构建循环逻辑以避免溢出的可能性,从而避免做任何棘手或不寻常的事情,这可能是一种更好的方法。

标签: rust unsigned integer-overflow unsigned-integer


【解决方案1】:

避免溢出的一种方法是用不同的方式构造循环.... Rust 没有明确的 do-while 语法,但它确实有 loop ,您可以从 break 中提取,甚至中断使用标签输出到任意数量的外部循环。

    loop {
        nums1[backwards_idx] = nums1[m_idx];
        if m_idx == 0 { break; }
        m_idx -= 1;
        backwards_idx -= 1;
    }

【讨论】:

    【解决方案2】:

    避免检查溢出的一种简单方法是确保您的 usize 类型(它们只会被减 1)从不从 0 开始那些循环。将 idx 类型重构为计数,并在我们想要获得索引时减 1,这是一种方法...

    impl Solution {
        pub fn merge(nums1: &mut Vec<i32>, m: i32, nums2: &mut Vec<i32>, n: i32) {
            let mut numbers_left: usize = (m + n) as usize;
            let (mut m_left, mut n_left) = (m as usize, n as usize);
            while m_left > 0 && n_left > 0 {
                let (nums1_elem, nums2_elem) = (nums1[m_left-1], nums2[n_left-1]);
                if nums1_elem <= nums2_elem {
                    nums1[numbers_left-1] = nums2_elem;
                    n_left = n_left - 1;
                } else {
                    nums1[numbers_left-1] = nums1_elem;
                    m_left = m_left - 1;
                }
                numbers_left = numbers_left - 1;
            }
            while m_left > 0 {
                nums1[numbers_left-1] = nums1[m_left-1];
                m_left = m_left - 1;
                numbers_left = numbers_left - 1;
            }
            while n_idx > 0 {
                nums1[numbers_left-1] = nums2[n_left-1];
                n_left = n_left - 1;
                numbers_left = numbers_left - 1;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-17
      • 1970-01-01
      • 1970-01-01
      • 2019-03-06
      • 1970-01-01
      • 2011-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多