vector - 在 Rust 中就地删除连续的重复元素
问题描述
我有以下python函数,可以就地删除连续重复的数字(意思是[0, 0, 1, 1, 1, 2, 2, 3]
变成[0, 1, 2, 3]
):
def del_consec_dupl(nums: List[int]):
for (idx, n) in enumerate(nums):
while idx < len(nums) - 1 and n == nums[idx + 1]:
del nums[idx]
它需要用 Rust 重写,同时尊重它必须就地工作而不分配额外向量/数组的约束。当试图从字面上翻译这个时:
fn del_consec_dupl(nums: &mut Vec<i32>) {
for (idx, n) in nums.iter().enumerate() {
while idx < nums.len() - 1 && *n == nums[idx + 1] {
nums.remove(idx);
}
}
}
将产生以下错误:
error[E0502]: cannot borrow `*nums` as immutable because it is also borrowed as mutable
--> src/main.rs:4:21
|
3 | for (idx, n) in nums.iter_mut().enumerate() {
| ---------------------------
| |
| mutable borrow occurs here
| mutable borrow later used here
4 | while idx < nums.len() - 1 && *n == nums[idx + 1] {
| ^^^^ immutable borrow occurs here
error[E0502]: cannot borrow `*nums` as immutable because it is also borrowed as mutable
--> src/main.rs:4:45
|
3 | for (idx, n) in nums.iter_mut().enumerate() {
| ---------------------------
| |
| mutable borrow occurs here
| mutable borrow later used here
4 | while idx < nums.len() - 1 && *n == nums[idx + 1] {
| ^^^^ immutable borrow occurs here
error[E0499]: cannot borrow `*nums` as mutable more than once at a time
--> src/main.rs:5:13
|
3 | for (idx, n) in nums.iter_mut().enumerate() {
| ---------------------------
| |
| first mutable borrow occurs here
| first borrow later used here
4 | while idx < nums.len() - 1 && *n == nums[idx + 1] {
5 | nums.remove(idx);
| ^^^^ second mutable borrow occurs here
error: aborting due to 3 previous errors
似乎无论我做什么,我只能解决 3 个中的 2 个。似乎这里的主要问题是试图在迭代内部发生变异时尝试引用向量的长度。
我需要一个unsafe
街区吗?或者你将如何解决它?
解决方案
我不会使用remove
which 在给定索引之后移动所有元素并且效率低下,而只是覆盖同一数组中的元素,通过使用索引来处理双借问题:
fn del_consec_dupl(nums: &mut Vec<i32>) {
let mut di = 0; // "destination" increment
for si in 1..nums.len() { // increment on the "source"
if nums[si] != nums[si-1] {
di += 1;
nums[di] = nums[si];
}
}
nums.truncate(di+1); // cut off the tail
}
没有必要在unsafe
这里使用。
推荐阅读
- r - 从文本中删除地理位置
- postgresql - 使用递归 CTE 的 Postgresql 节点遍历
- java - 在 Maven 的其他模块中看不到依赖模块的变化
- flutter - Flutter 必须延迟更新 showModalBottomSheet 中的变量
- reactjs - 你可以在 React 组件的返回函数中设置外部 HTML 吗?
- python - 我如何读取里面有字节的文件
- ios - 呈现 UIAlertController 时无法关闭 UIViewController
- nodemailer - Ghost Blogs - 作者邀请电子邮件
- azure - Azure AD B2C - 多应用服务的 CORS 策略问题
- javascript - 在 useEffect 中测试组件调用 API