Я пытаюсь вернуть сумму 3 самых больших чисел в таком массиве:
fn max_tri_sum(arr: &[i32]) -> i32 {
arr.sort();
arr[0]+arr[1]+arr[2]
}
но я продолжаю получать эту ошибку:
error[E0596]: cannot borrow `*arr` as mutable, as it is behind a `&` reference
fn max_tri_sum(arr: &[i32]) -> i32 {
------ help: consider changing this to be a mutable reference: `&mut [i32]`
arr.sort();
^^^ `arr` is a `&` reference, so the data it refers to cannot be borrowed as mutable
Я не должен менять arr: &[i32]
на arr: &mut [i32]
из-за некоторых ограничений. Итак, что я могу с этим поделать?
P.S. Я пытался клонировать arr
в изменяемую переменную, но получил другие ошибки:
fn max_tri_sum(arr: &[i32]) -> i32 {
let a: &mut [i32] = *arr.clone();
a.sort();
a[0]+a[1]+a[2]
}
Вы также можете использовать BinaryHeap для хранения трех самых больших значений и замены наименьшего значения при циклическом просмотре массива:
use std::collections::BinaryHeap;
fn max_tri_sum(arr: &[i32]) -> i32 {
let mut heap = BinaryHeap::new();
heap.push(-arr[0]);
heap.push(-arr[1]);
heap.push(-arr[2]);
for e in arr[3..].iter() {
if -e < *heap.peek().unwrap() {
heap.pop();
heap.push(-e);
}
}
-heap.drain().sum::<i32>()
}
Или, если вы предпочитаете вариант сортировки, вы можете преобразовать срез в вектор:
fn max_tri_sum(arr: &[i32]) -> i32 {
let mut arr1 = arr.to_vec();
arr1.sort_by(|a, b| b.cmp(a));
arr1[0] + arr1[1] + arr1[2]
}
В Rust у вас не может быть переменной, которая имеет как ссылку, так и изменяемую ссылку в одной и той же области видимости.
У вас есть несколько вариантов:
fn max_tri_sum(arr: &[i32]) -> i32 {
let mut maxes = [0, 0, 0];
for &el in arr {
if el > maxes[0] && el < maxes[1] {
maxes[0] = el;
} else if el > maxes[1] && el < maxes[2] {
if maxes[1] > maxes[0] {
maxes[0] = maxes[1];
}
maxes[1] = el;
} else if el > maxes[2] {
if maxes[2] > maxes[1] {
maxes[1] = maxes[2];
}
maxes[2] = el;
}
}
maxes[0] + maxes[1] + maxes[2]
}
Vec
из фрагмента, а затем выполнить над ним все операции (что требует выделения, но должно подойти для небольших Vec
). fn max_tri_sum(arr: &[i32]) -> i32 {
let mut arr = Vec::from(arr);
arr.sort();
arr[0] + arr[1] + arr[2]
}
Я также хотел бы отметить, что sort
сортируется от меньшего к большему, поэтому индекс 0, 1, 2, ...
будет наименьшим значением в массиве, а я не думаю, что вы хотите это сделать!
@AngelicosPhosphoros Хороший вопрос! я обновлю свой ответ
Ваша первая версия также требует выделения кучи. Лучше использовать
let mut maxes = [0,0,0];
вместоvec!
.