please help me to solve the error during selection sorting due to change in scope of the variable
for i in 0..array.len()
{
position = i;
for j in (i+1)..array.len()-1
{
if array[position] > array[j]
{
position =j;
}
}
if position != i
{
swap = array[i];
array[i] = array[j];
array[j] = swap;
}
}
/* error:cannot find value `j` in this scope*/
how to solve this using reference and borrowing or using any other method?
It's hard to advise more idiomatic Rust code here, because I assume you're deliberately writing bubble sort. It's a poor algorithm, and it doesn't have an elegant way to express in Rust.
for i in array.len() loops are generally discouraged in Rust (they're slower than for element in array), but in your case you have two nested loops that need to mutate elements, so doing it with iterators makes it tricky. The inner loop could use a slice from split_at_mut(i+1), and use mem::swap to swap elements.
If you want to practice Rust on simple problems, try Rust on Exercism
Just a nit: this is actually selection sort with a minor bug that the compiler caught for you: the final swap was supposed to be between positions i and position (as noted by @cuviper) which should get rid of the error.
I'm sure there are multiple ways to write a rust-ier solution. Here's one:
Edit: Actually, look at the one 2 posts down which is a bit easier to read.
fn selection_sort(mut array: &mut [u32]) {
// Instead of an index going through the array,
// we will keep shrinking the array slice down
// to its unsorted portion.
while array.len() > 0 {
// Find the (index, value) with the min
// value in the remaining slice.
let min_val_pos = array
.iter().copied().enumerate()
.min_by_key(|&(_index, val)| val);
if let Some((min_pos, _)) = min_val_pos {
array.swap(0, min_pos);
}
array = &mut array[1..];
}
}
I'm not sure I understand the criticism. Presumably you're not criticizing the the one in the original post – the one that wasn't recognized as selection sort?
If you are referring to the example I wrote above, I completely understand that style is unfamiliar to some and an immediate turn-off. However, it was written to actually read like the description of the Selection Sort algorithm (bullets are mine to emphasize the 3 steps):
The algorithm proceeds by
finding the smallest (or largest, depending on sorting order) element in the unsorted sublist,
exchanging (swapping) it with the leftmost unsorted element (putting it in sorted order), and
moving the sublist boundaries one element to the right.
Those are exactly the 3 lines I wrote above. In this form, it doesn't require complicated reasoning about the presence of off-by-one errors, which I often have to do with in-place sorts written in the style I would in C.
Perhaps this slightly modified version emphasizes a bit better that the first line computes the index of the min.
fn selection_sort(mut array: &mut [u32]) {
// Instead of an index going through the array,
// we will keep shrinking the array slice down
// to its unsorted portion.
while array.len() > 0 {
let index_of_min = array
.iter().copied().enumerate()
.min_by_key(|&(_index, val)| val)
.map(|(index, _val)| index);
if let Some(index_of_min) = index_of_min {
array.swap(0, index_of_min);
}
array = &mut array[1..];
}
}
Don't mind me, I have been programming with real variables, arrays, indices and loops for so long that I have a hard time following along when everything disappears and is hidden behind behind words in the modern functional style.
Hopefully I'll get comfortable with it with enough practice.