求平均数就是将Vec中的元素全部相加然后除以元素个数,值得注意的是Rust中没有隐式类型转换,需要将除数和被除数强转为f64之后相除才能得到浮点数。
求中位数就是将Vec中的元素排序后,升序或者降序都行,这里直接调用Vec的sort方法,然后看元素个数,如果是奇数个,取排序后最中间的那个数作中位数,如果是偶数个,去排序后最中间两个数的平均值,同样注意类型转换问题。
求众数首先要从众数的定义入手:
一般来说,一组数据中,出现次数最多的数就叫这组数据的众数。
例如:1,2,3,3,4的众数是3。
但是,如果有两个或两个以上个数出现次数都是最多的,那么这几个数都是这组数据的众数。
例如:1,2,2,3,3,4的众数是2和3。
还有,如果所有数据出现的次数都一样,那么这组数据没有众数。
例如:1,2,3,4,5没有众数。
所以我们先用一个HashMap来统计元素出现的次数,key是元素,value是它的出现次数。然后因为众数可能不止一个,所以用一个Vec来存储众数的备选,为什么是备选,因为我希望在HashMap构造完之后,只用一遍遍历HashMap就可以求出众数。
然后我们定义一个众数出现次数的当前最大值,初始为0,遍历HashMap当出现次数(value)大于此值是清空备选Vec,清空方法这里选的是重新赋值即mode_bak_vec=Vec::new(),将当前的元素(key)插入备选Vec,同时更新当前最大值为value。如果相等直接插入,小于不处理。这样就可以保证最终当前最大值就是最大的value值,并且备选数组里是所有等于最大value的key值。如果数组大小等于HashMap的键值对个数(也就是size),说明所有元素的出现个数一样,这种情况下众数不存在,所以可以用一个Option<Vec<i32>>来装。
代码如下:
use std::io;
use std::collections::HashMap;
fn main() {
let mut vt:Vec<i32>=Vec::new();
println!("Please input the size of the array");
let k=read_num();
println!("Input the {} members of the array,each number on one line",k);
let mut sum_x=0;
for t in 0..k{
vt.push(read_num());
sum_x+=&vt[t as usize];
}
vt.sort();
let d=(k/2) as usize;
let median=match k%2 {
1 => vt[d] as f64,
_ => {
let p=d-1;
(vt[p]+vt[d]) as f64/2.0
}
};
let mut mode:Option<Vec<i32>>=Option::None;
let mut hash_m=HashMap::new();
for s in &vt{
let count=hash_m.entry(s).or_insert(0);
*count+=1;
}
let mut mode_bak_vec=Vec::new();
let mut max_num=0;
for i in &hash_m{
if max_num==*i.1
{
mode_bak_vec.push(**i.0);
}else if max_num<*i.1 {
mode_bak_vec=Vec::new();
mode_bak_vec.push(**i.0);
max_num=*i.1;
}
}
if mode_bak_vec.len()!=hash_m.len() as usize
{
mode=Option::Some(mode_bak_vec);
}
let avg_num=sum_x as f64 / k as f64;
println!("The sorted arr is {:?}",vt);
println!("The hash_map is {:?}",hash_m);
println!("The median is {}",median);
println!("The modes are {:?}",mode);
println!("The average is {}",avg_num);
}
fn read_num()->i32
{
let mut s=String::new();
io::stdin().read_line(&mut s).expect("raed error");
s.trim().parse().expect("not a num")
}