Rust学习—示例3
描述:难以置信的无聊事物博物馆
令人难以置信的沉闷事物博物馆想摆脱一些展览。室内建筑师米里亚姆想出了一个计划,以去除最无聊的展览。她给这些展览打分,然后把打分最低的那个拿走。
然而,就在她完成对所有展览的评级时,她要去参加一个重要的展览会,所以她要求你写一个程序,告诉她在删除了最低的那个展览之后的项目评级。
任务
给定一个整数数组,去除最小的值。不要改变原始数组/列表。如果有多个元素具有相同的值,则删除索引较低的那个。如果你得到一个空数组/列表,返回一个空数组/列表。
不要改变剩下的元素的顺序。
示例
* Input: [1,2,3,4,5], output = [2,3,4,5]
* Input: [5,3,2,1,4], output = [5,3,2,4]
* Input: [2,2,1,2,1], output = [2,2,2,1]
代码实现
#[cfg(test)]
mod tests {
use rand::{thread_rng, Rng};
use rand::seq::SliceRandom;
use super::remove_smallest;
use std::iter;
//官方给出的解决方案
fn reference_solution(numbers: &[u32]) -> Vec<u32> {
match numbers.iter().min() {
None => Vec::new(),
Some(n) => {
let i = numbers.iter().position(|x| x == n).unwrap();
numbers[..i].iter().chain(numbers[i+1..].iter()).map(|x| *x).collect()
}
}
}
const ERR_MSG: &str = "\nYour result (left) did not match the expected output (right)";
fn dotest(a: &[u32], expected: &[u32]) {
assert_eq!(remove_smallest(a), expected, "{ERR_MSG} with numbers = {a:?}")
}
#[test]
fn fixed_tests() {
dotest(&[1, 2, 3, 4, 5], &[2, 3, 4, 5]);
dotest(&[1, 2, 3, 4], &[2, 3, 4]);
dotest(&[5, 3, 2, 1, 4], &[5, 3, 2, 4]);
dotest(&[1, 2, 3, 1, 1], &[2, 3, 1, 1]);
dotest(&[], &[]);
dotest(&[1], &[]);
}
#[test]
fn random_tests() {
let mut rng = thread_rng();
let mut lengths = iter::once(0).chain(iter::once(1)).chain((0..98).map(|_| rng.gen_range(2..=10))).collect::<Vec<_>>();
lengths.shuffle(&mut rng);
for ln in lengths {
let arr = &(0..ln).map(|_| rng.gen_range(1..100)).collect::<Vec<_>>();
dotest(arr, &reference_solution(arr));
}
}
}
fn remove_smallest(numbers: &[u32]) -> Vec<u32> {
if numbers.is_empty(){
return vec![];
}
//todo!()
let (mut index, mut num) = (0, numbers[0]);
let mut numbers = Vec::from(numbers);
for (i, n) in numbers.iter().enumerate() {
if num > *n{
num = *n;
index = i;
}
}
numbers.remove(index);
numbers
}
其他可参考代码
//表示膜拜
use itertools::Itertools;
//1
fn remove_smallest(numbers: &[u32]) -> Vec<u32> {
let mut numbers = numbers.to_vec();
match numbers.iter().position_min() {
None => numbers,
Some(m) => {numbers.remove(m); numbers}
}
}
//2
use itertools::Itertools;
fn remove_smallest(numbers: &[u32]) -> Vec<u32> {
let pos = numbers.iter().position_min().unwrap_or(0);
numbers.iter().take(pos).chain(numbers.iter().skip(pos + 1)).cloned().collect()
}
//3 这个实现方式还是很好懂的
fn remove_smallest(numbers: &[u32]) -> Vec<u32> {
let mut result = Vec::new();
if numbers.len() == 0 {
return result;
}
let mut lowest_number = &numbers[0];
let mut flag = true;
for number in numbers {
if number < lowest_number {
lowest_number = number
}
}
for number in numbers {
if number == lowest_number && flag {
flag = false;
} else {
result.push(*number as u32);
}
};
result
}
//4
fn remove_smallest(numbers: &[u32]) -> Vec<u32> {
if let Some(min) = numbers.iter().min() {
if let Some(pos) = numbers.iter().position(|&x| x == *min) {
let mut result = Vec::from(numbers);
result.remove(pos);
return result;
}
}
vec![]
}