rust中map和set的基本使用

1.HahsMap

https://rustwiki.org/zh-CN/std/collections/struct.HashMap.html

跟着文档,查看一下hashmap的方法,调试,输出一下,就能学会使用了。

use std::collections::HashMap;
use std::any::type_name;
//输出变量类型
fn print_type_of<T>(_: &T) {
    println!("{}", type_name::<T>());
}

//最基本的创建hashmap
fn test1() {
    // let mut m = HashMap::new(); //std::collections::hash::map::HashMap<i32, i32>
    let mut m = HashMap::with_capacity(7);  //因为后面有插值,才不用自定类型
    // let mut m:HashMap<i32,i32> = HashMap::new();    //std::collections::hash::map::HashMap<i32, i32>
    m.insert(0,1);
    m.insert(2,3);
    print_type_of(&m);
    //为什么key和v都是i32的类型?
    //这里m不使用引用,就会获取m的所有权,后面将不能再使用m
    //不使用引用,k,v都是i32,m使用引用,k,v都是&i32
    for (k,v) in &m {
        println!("{} {}",k,v);
        print_type_of(&v);
        print_type_of(&k);
    }
    println!("{}",m.contains_key(&2));  
}
//hashmap常规使用
fn test2() {
    let range = 0..5;
    // let mut m:HashMap<i32,i32> = range.map(|i|(i,i+1)).collect();
    let mut m = HashMap::from([
        (0,1),(1,2),(2,3),(3,4),(4,5)
    ]);
    m.insert(5,7);
    print_type_of(&m);  //std::collections::hash::map::HashMap<i32, i32>
    println!("len: {}",m.len());
    println!("capacity: {}",m.capacity());
    //输出是无序的
    for (k,v) in &m {
        println!("k: {},v: {}",k,v);
        print_type_of(&k);
        print_type_of(&v);
    }
    //查询是否包含指定key
    println!("{}",m.contains_key(&7));  //false
    println!("{}",m.contains_key(&5));  //true
    //获取指定key的value
    println!("{:?}",m.get(&7)); //None
    println!("{:?}",m.get(&5)); //Some(7)
    let mut five = m.get_mut(&5);
    // let mut num = 999;   //这样改是没有用的,必须在模式匹配中才有效
    // five.replace(&mut num);
    match five {
        Some(ref mut v) => {
            **v = 999;
            print_type_of(&v);  //&mut &mut i32
        },
        _ =>{},
    }
    println!("{}",m[&5]);       //999

    //移除指定key
    println!("{:?}",m.remove(&7));  //None
    println!("{:?}",m.remove(&5));  //Some(999)

    print_type_of(&m.remove_entry(&3)); //core::option::Option<(i32, i32)>
    println!("{:?}",m.remove_entry(&2));//Some((2, 3))

    print_type_of(&m.get_key_value(&1));    //core::option::Option<(&i32, &i32)>
    println!("{:?}",m.get_key_value(&1));   //Some((1, 2)),自动解引用了
    //直接通过索引找key,找不存在的key就会panic
    println!("{}",m[&5]);   //no entry found for key,然后panic
}

fn get_five() ->i32 {
    5
}

//map中entry的用法
fn test3() {
    let range  = 0..6;
    // let mut m:HashMap<i32,i32> = range.map(|i|(i,i+2)).collect();
    let mut m:HashMap<i32,i32> = (0..6).map(|i|(i,i+2)).collect();

    // print_type_of(&m.entry(0));
    println!("len {}",m.len());

    //最好是不要创建变量来调用m.entry(),e的每次调用都会消耗掉所有权,从而需要重新调用m.entry()
    /*let e = m.entry(10);
    print_type_of(&e); //Enum std::collections::hash_map::Entry std::collections::hash::map::Entry<i32, i32>
    e.or_insert(100);   //不存在的key,就会创建并插入
    // let e = m.entry(10);

    println!("{}",e.or_insert(100));
    // let e = m.entry(10);

    *e.or_insert(100) = 66;
    // let e = m.entry(10);

    println!("{}",e.or_insert(100));
    
    return;*/
    //or_insert(v) 直接插入一个值

    /*
    m.entry(10).or_insert(100);
    println!("len {}",m.len()); //长度增加了
    println!("{:?}",m.entry(10));
    *m.entry(10).or_insert(66) = 66;
    println!("{:?}",m.entry(10));
    */

    //or_insert_with(||v) 利用闭包来创建插入的值
    /*
    m.entry(10).or_insert_with(||100);
    println!("len {}",m.len()); //长度增加了
    println!("{:?}",m.entry(10));
    *m.entry(10).or_insert_with(||100) = 66;
    println!("{:?}",m.entry(10));
    */

    /*fn Six()->i32 {
        6
    }
    // let six = || 6;
    // let six = ||->i32 {6};
    m.entry(10).or_insert_with(Six);
    // m.entry(10).or_insert_with(get_five);   //闭包也行,函数也行
    println!("len {}",m.len()); //长度增加了
    println!("{:?}",m.entry(10));

    *m.entry(10).or_insert_with(||100) = 66;
    println!("{:?}",m.entry(10));
    */
    // return;

    //这样使用,就像最开始创建m时,根据k,生成v
    m.entry(10).or_insert_with_key(|k|k+2);
    println!("{:?}",m.entry(10));
    println!("len {}",m.len()); //长度增加了
    *m.entry(10).or_insert_with_key(|k|k+2) = 66;

    println!("{:?}",m.entry(10));

    m.entry(10).and_modify(|e| *e*=10);    //and_modify,只能在entry存在时,进行修改
    println!("{:?}",m.entry(10));
    m.entry(100).and_modify(|e| *e*=10);    //and_modify,entry不存在时
    println!("{:?}",m.entry(100));  //Entry(VacantEntry(100))

    m.entry(100).or_default();
    println!("{:?}",m.entry(100));      //插入了i32的默认值,为0
    *m.entry(100).or_default() = 166;
    println!("{:?}",m.entry(100));  

    /*
    //entry,使用后会消耗
    let e = m.entry(100);
    let v = e.or_default();
    *v = 166;
    println!("{:?}",m.entry(100));  
    let e = m.entry(100);
    let v = e.or_insert(66);
    *v = 188;
    println!("{:?}",m.entry(100));  
    */
}
fn test4() {
    let mut m = HashMap::from([
        ("a",1),("b",2),("c",3)
    ]);

    //m.keys(),返回键的引用
    for k in m.keys() {
        println!("{}",k);
        print_type_of(&k);  //&&str
    }

    /*
    //into_keys(),将获取m的所有权
    let keys:Vec<_> = m.into_keys().collect();  //会消耗m,m将失去所有权
    print_type_of(&keys);   //alloc::vec::Vec<&str>
    println!("{:?}",keys);  //["a", "b", "c"]
    // print_type_of(&m);   //不能再使用m
    */
    
    //m.values_mut(),返回值的可变引用
    for v in m.values_mut() {
        *v *=10;
        print_type_of(&v);  //&mut i32
    }
    //m.values(),返回值的引用
    for v in m.values() {
        println!("{}",v);
        print_type_of(&v);  //&i32
    }

    /*
    //into_values(),将获取m的所有权
    let values:Vec<_> = m.into_values().collect();
    print_type_of(&values); //alloc::vec::Vec<i32>
    println!("{:?}",values);
    // print_type_of(&m);   //不能再使用m
    */
    
    //不加&也会获取m的所有权
    for (k,v) in &m {
        println!("{} {}",k,v);
        print_type_of(&k);
        print_type_of(&v);
        break;
    }
    print_type_of(&m);   //遍历不加&就不能再使用m

    //k和v都是引用,但是v可变
    for (_,v) in m.iter_mut() {
        *v +=16;
        print_type_of(&v);  //&mut i32
    }
    //使用m.iter(),效果和&m一致
    for (k,v) in m.iter() {
        println!("{} {}",k,v);
        print_type_of(&k);
        print_type_of(&v);
        break;
    }
    print_type_of(&m);
    println!("{:?}",m); //{"c": 46, "a": 26, "b": 36}

    //k:&&str,v:&mut i32同迭代器,都是引用
    //同模式匹配一直,这里可以是ref k ,k,&k ,k的类型分别是&&&str,&&str,&str
    //原地操作,删除返回false的key-value
    m.retain(|k,v|{
        print_type_of(&k);
        print_type_of(&v);
        if v==&36  || *v == 36 {
            *v = 999;
        }
        true
    });
    println!("{:?}",m); //{"c": 46, "a": 26, "b": 36}

    let cm:Vec<_> = m.clone().into_iter().collect();
    print_type_of(&cm);     //alloc::vec::Vec<(&str, i32)>
    println!("{:?}",cm);    //[("a", 26), ("b", 999), ("c", 46)]
    print_type_of(&m.clone().into_iter());  //std::collections::hash::map::IntoIter<&str, i32>
    print_type_of(&m.iter());               //std::collections::hash::map::Iter<&str, i32>
    print_type_of(&m.iter_mut());           //std::collections::hash::map::IterMut<&str, i32>

    println!("{}",m.capacity());
    m.clear();  //容量还在,但是数据清除了
    println!("{}",m.capacity());

}
fn main() {
    test4();
}

2.BTreemap

个人感觉使用起来和HashMap没有太大区别,除了没有capacity这个属性,所以也没有with_capacity()来新建

use std::collections::BTreeMap;
use std::any::type_name;
//输出变量类型
fn print_type_of<T>(_: &T) {
    println!("{}", type_name::<T>());
}

//最基本的创建hashmap
fn test1() {
    // let mut m = BTreeMap::new(); //std::collections::hash::map::BTreeMap<i32, i32>
    let mut m:BTreeMap<i32,i32> = BTreeMap::new();    //std::collections::hash::map::BTreeMap<i32, i32>
    m.insert(0,1);
    m.insert(2,3);
    print_type_of(&m);
    //为什么key和v都是i32的类型?
    //这里m不使用引用,就会获取m的所有权,后面将不能再使用m
    //不使用引用,k,v都是i32,m使用引用,k,v都是&i32
    for (k,v) in &m {
        println!("{} {}",k,v);
        print_type_of(&v);
        print_type_of(&k);
    }
    println!("{}",m.contains_key(&2));  
}
//hashmap常规使用
fn test2() {
    let range = 0..5;
    // let mut m:BTreeMap<i32,i32> = range.map(|i|(i,i+1)).collect();
    let mut m = BTreeMap::from([
        (0,1),(1,2),(2,3),(3,4),(4,5)
    ]);
    m.insert(5,7);
    print_type_of(&m);  //std::collections::hash::map::BTreeMap<i32, i32>
    println!("len: {}",m.len());
    // println!("capacity: {}",m.capacity());
    //输出是无序的
    for (k,v) in &m {
        println!("k: {},v: {}",k,v);
        print_type_of(&k);
        print_type_of(&v);
    }
    //查询是否包含指定key
    println!("{}",m.contains_key(&7));  //false
    println!("{}",m.contains_key(&5));  //true
    //获取指定key的value
    println!("{:?}",m.get(&7)); //None
    println!("{:?}",m.get(&5)); //Some(7)
    let mut five = m.get_mut(&5);
    // let mut num = 999;   //这样改是没有用的,必须在模式匹配中才有效
    // five.replace(&mut num);
    match five {
        Some(ref mut v) => {
            **v = 999;
            print_type_of(&v);  //&mut &mut i32
        },
        _ =>{},
    }
    println!("{}",m[&5]);       //999

    //移除指定key
    println!("{:?}",m.remove(&7));  //None
    println!("{:?}",m.remove(&5));  //Some(999)

    print_type_of(&m.remove_entry(&3)); //core::option::Option<(i32, i32)>
    println!("{:?}",m.remove_entry(&2));//Some((2, 3))

    print_type_of(&m.get_key_value(&1));    //core::option::Option<(&i32, &i32)>
    println!("{:?}",m.get_key_value(&1));   //Some((1, 2)),自动解引用了
    //直接通过索引找key,找不存在的key就会panic
    println!("{}",m[&5]);   //no entry found for key,然后panic
}
// type func = fn()->i32;   //这样定义的用处是什么呢
fn get_five() ->i32 {
    5
}

//map中entry的用法
fn test3() {
    let range  = 0..6;
    // let mut m:BTreeMap<i32,i32> = range.map(|i|(i,i+2)).collect();
    let mut m:BTreeMap<i32,i32> = (0..6).map(|i|(i,i+2)).collect();

    // print_type_of(&m.entry(0));
    println!("len {}",m.len());

    //最好是不要创建变量来调用m.entry(),e的每次调用都会消耗掉所有权,从而需要重新调用m.entry()
    /*let e = m.entry(10);
    print_type_of(&e); //Enum std::collections::hash_map::Entry std::collections::hash::map::Entry<i32, i32>
    e.or_insert(100);   //不存在的key,就会创建并插入
    // let e = m.entry(10);

    println!("{}",e.or_insert(100));
    // let e = m.entry(10);

    *e.or_insert(100) = 66;
    // let e = m.entry(10);

    println!("{}",e.or_insert(100));
    
    return;*/
    //or_insert(v) 直接插入一个值

    /*
    m.entry(10).or_insert(100);
    println!("len {}",m.len()); //长度增加了
    println!("{:?}",m.entry(10));
    *m.entry(10).or_insert(66) = 66;
    println!("{:?}",m.entry(10));
    */

    //or_insert_with(||v) 利用闭包来创建插入的值
    /*
    m.entry(10).or_insert_with(||100);
    println!("len {}",m.len()); //长度增加了
    println!("{:?}",m.entry(10));
    *m.entry(10).or_insert_with(||100) = 66;
    println!("{:?}",m.entry(10));
    */

    /*fn Six()->i32 {
        6
    }
    // let six = || 6;
    // let six = ||->i32 {6};
    m.entry(10).or_insert_with(Six);
    // m.entry(10).or_insert_with(get_five);   //闭包也行,函数也行
    println!("len {}",m.len()); //长度增加了
    println!("{:?}",m.entry(10));

    *m.entry(10).or_insert_with(||100) = 66;
    println!("{:?}",m.entry(10));
    */
    // return;

    //这样使用,就像最开始创建m时,根据k,生成v
    m.entry(10).or_insert_with_key(|k|k+2);
    println!("{:?}",m.entry(10));
    println!("len {}",m.len()); //长度增加了
    *m.entry(10).or_insert_with_key(|k|k+2) = 66;

    println!("{:?}",m.entry(10));

    m.entry(10).and_modify(|e| *e*=10);    //and_modify,只能在entry存在时,进行修改
    println!("{:?}",m.entry(10));
    m.entry(100).and_modify(|e| *e*=10);    //and_modify,entry不存在时
    println!("{:?}",m.entry(100));  //Entry(VacantEntry(100))

    m.entry(100).or_default();
    println!("{:?}",m.entry(100));      //插入了i32的默认值,为0
    *m.entry(100).or_default() = 166;
    println!("{:?}",m.entry(100));  

    /*
    //entry,使用后会消耗
    let e = m.entry(100);
    let v = e.or_default();
    *v = 166;
    println!("{:?}",m.entry(100));  
    let e = m.entry(100);
    let v = e.or_insert(66);
    *v = 188;
    println!("{:?}",m.entry(100));  
    */
}
fn test4() {
    let mut m = BTreeMap::from([
        ("a",1),("b",2),("c",3)
    ]);

    //m.keys(),返回键的引用
    for k in m.keys() {
        println!("{}",k);
        print_type_of(&k);  //&&str
    }

    /*
    //into_keys(),将获取m的所有权
    let keys:Vec<_> = m.into_keys().collect();  //会消耗m,m将失去所有权
    print_type_of(&keys);   //alloc::vec::Vec<&str>
    println!("{:?}",keys);  //["a", "b", "c"]
    // print_type_of(&m);   //不能再使用m
    */
    
    //m.values_mut(),返回值的可变引用
    for v in m.values_mut() {
        *v *=10;
        print_type_of(&v);  //&mut i32
    }
    //m.values(),返回值的引用
    for v in m.values() {
        println!("{}",v);
        print_type_of(&v);  //&i32
    }

    /*
    //into_values(),将获取m的所有权
    let values:Vec<_> = m.into_values().collect();
    print_type_of(&values); //alloc::vec::Vec<i32>
    println!("{:?}",values);
    // print_type_of(&m);   //不能再使用m
    */
    
    //不加&也会获取m的所有权
    for (k,v) in &m {
        println!("{} {}",k,v);
        print_type_of(&k);
        print_type_of(&v);
        break;
    }
    print_type_of(&m);   //遍历不加&就不能再使用m

    //k和v都是引用,但是v可变
    for (_,v) in m.iter_mut() {
        *v +=16;
        print_type_of(&v);  //&mut i32
    }
    //使用m.iter(),效果和&m一致
    for (k,v) in m.iter() {
        println!("{} {}",k,v);
        print_type_of(&k);
        print_type_of(&v);
        break;
    }
    print_type_of(&m);
    println!("{:?}",m); //{"c": 46, "a": 26, "b": 36}

    //k:&&str,v:&mut i32同迭代器,都是引用
    //同模式匹配一直,这里可以是ref k ,k,&k ,k的类型分别是&&&str,&&str,&str
    //原地操作,删除返回false的key-value
    m.retain(|k,v|{
        print_type_of(&k);
        print_type_of(&v);
        if v==&36  || *v == 36 {
            *v = 999;
        }
        true
    });
    println!("{:?}",m); //{"c": 46, "a": 26, "b": 36}

    let cm:Vec<_> = m.clone().into_iter().collect();
    print_type_of(&cm);     //alloc::vec::Vec<(&str, i32)>
    println!("{:?}",cm);    //[("a", 26), ("b", 999), ("c", 46)]
    print_type_of(&m.clone().into_iter());  //std::collections::hash::map::IntoIter<&str, i32>
    print_type_of(&m.iter());               //std::collections::hash::map::Iter<&str, i32>
    print_type_of(&m.iter_mut());           //std::collections::hash::map::IterMut<&str, i32>

    // println!("{}",m.capacity());
    // m.clear();  //容量还在,但是数据清除了
    // println!("{}",m.capacity());

}
fn main() {
    test4();
}

代码和HashMap几乎没有什么不同,就是没有capacity()了,需要注释掉

3.HashSet

#![feature(hash_set_entry)]
use std::collections::HashSet;
use std::any::type_name;
//输出变量类型
fn print_type_of<T>(_: &T) {
    println!("{}", type_name::<T>());
}
fn value(mut v:i32) ->i32{
    v = v*10 + 1;
    v
}
fn test() {
    // let mut s:HashSet<i32> = (0..11).map(|mut v|{
    //     v*=10;
    //     v
    // }).collect();
    //闭包里面,直接给一个函数也是可以的
    let h = value;
    print_type_of(&value);
    let mut s:HashSet<i32> = (0..11).map(h).collect();
    //let mut s:HashSet<i32> = (0..11).map(value).collect();
    println!("{:?}",s);
}
fn main() {
    // let mut s = HashSet::new();
    // let mut s = HashSet::with_capacity(5);
    let mut s = HashSet::from([1,2,3,4,5,6]);
    // s.insert(5);
    // s.insert(6);
    print_type_of(&s);
    println!("{:?}",s);

    //^ value borrowed here after move,遍历时不使用引用也会获取所有权
    for v in &s {
        print_type_of(&v);
        println!("{}",v);
    }

    //二者的遍历效果是一致的,但是iter()不会带走所有权
    println!("-----------");

    //retain的参数也是引用,也可以使用ref v,v,&v,分别是&&i32,&i32,i32
    s.retain(|v|{
        print_type_of(&v);
        *v>=3   //删掉<3的元素
    });
    println!("移除3 {}",s.remove(&3));//true
    for v in s.iter() {
        print_type_of(&v);
        println!("{}",v);
    }
    println!("{}",s.contains(&5));
    println!("{:?}",s.get(&6)); //Some(6)
    println!("{:?}",s.get(&10));    //None
    println!("{}",s.get_or_insert(10)); //实验性的,要在顶上添加 #![feature(hash_set_entry)]
    print_type_of(&s.get_or_insert(10));    //&i32
    // println!("{}",s.get_or_insert_with(&100,|_|66)); //测试失败

    println!("{}",s.len());
    println!("{:?}",s);
    println!("----------");
    println!("first replace 50 {:?}",s.replace(50)); //没有,就返回Some(50),然后插入,有,就和s.get(&50)一样了
    println!("second replace 50 {:?}",s.replace(50)); //Some(50)
    println!("{:?}",s.get(&50));    //Some(50)
    println!("{:?}",s.take(&50));   //有,就删除,并返回Some(50),没有,就是None
    println!("{:?}",s.take(&50));   //None

    //插入一下Option的take和replace方法
    {
        let mut a = Some(188);
        println!("{:?}",a); //Some(188)
        let b = a.take();   //有,就拿走,a就变成None
        println!("{:?}",b); //Some(188)
        println!("{:?}",a); //None
        println!("{:?}",a.take());  //None
        let c = a.replace(166); //c变成a原来的值,a变成新的值
        println!("{:?}",a); //Some(166)
        println!("{:?}",c); //None
        let c = a.replace(721);
        println!("{:?}",a); //Some(721)
        println!("{:?}",c); //Some(166)
    }
    println!("---------");
    println!("{:?}",s);
    let set:HashSet<i32> = (1..11).map(|v|v).collect();
    println!("{:?}",set);
    println!("{}",s.is_subset(&set));   //s是否是set的子集
    println!("{}",set.is_superset(&s)); //set是否是s的超集
    println!("{}",s.is_disjoint(&set)); //有无交集,有
    let s1 = HashSet::from([99,98,100]);
    println!("{}",s1.is_disjoint(&set)); //有无交集,无

    s.insert(99);
    s.insert(98);
    println!("{:?}",s.difference(&s1)); //s去掉和s1相交的部分
    println!("{:?}",s1.difference(&s)); //s1去掉和s相交的部分

    //效果就像是两个集合都去掉重叠的部分,然后合并
    println!("{:?}",s.symmetric_difference(&s1));
    println!("{:?}",s1.symmetric_difference(&s));

    println!("{:?}",s.intersection(&s1));   //求交集
    println!("{:?}",s.union(&s1));    //求并集

    //清除后,就是空的了
    // s.clear();
    // println!("{}",s.is_empty());
}

4.BTreeSet

使用起来和HashSet没有太大区别,除了键是有序的,并且没有get_or_insert()德国方法

#![feature(hash_set_entry)]
use std::collections::BTreeSet;
use std::any::type_name;
//输出变量类型
fn print_type_of<T>(_: &T) {
    println!("{}", type_name::<T>());
}
fn main() {
    // let mut s = BTreeSet::new();
    // let mut s = BTreeSet::with_capacity(5);
    let mut s = BTreeSet::from([1,2,3,4,5,6]);
    // s.insert(5);
    // s.insert(6);
    print_type_of(&s);
    println!("{:?}",s);

    //^ value borrowed here after move,遍历时不使用引用也会获取所有权
    for v in &s {
        print_type_of(&v);
        println!("{}",v);
    }

    //二者的遍历效果是一致的,但是iter()不会带走所有权
    println!("-----------");

    //retain的参数也是引用,也可以使用ref v,v,&v,分别是&&i32,&i32,i32
    s.retain(|v|{
        print_type_of(&v);
        *v>=3   //删掉<3的元素
    });
    println!("移除3 {}",s.remove(&3));//true
    for v in s.iter() {
        print_type_of(&v);
        println!("{}",v);
    }
    println!("{}",s.contains(&5));
    println!("{:?}",s.get(&6)); //Some(6)
    println!("{:?}",s.get(&10));    //None

    //并没有get_or_insert()方法
    // println!("{}",s.get_or_insert(10)); //实验性的,要在顶上添加 #![feature(hash_set_entry)]
    // print_type_of(&s.get_or_insert(10));    //&i32
    // println!("{}",s.get_or_insert_with(&100,|_|66)); //测试失败

    println!("{}",s.len());
    println!("{:?}",s);
    println!("----------");
    println!("first replace 50 {:?}",s.replace(50)); //没有,就返回Some(50),然后插入,有,就和s.get(&50)一样了
    println!("second replace 50 {:?}",s.replace(50)); //Some(50)
    println!("{:?}",s.get(&50));    //Some(50)
    println!("{:?}",s.take(&50));   //有,就删除,并返回Some(50),没有,就是None
    println!("{:?}",s.take(&50));   //None

    //插入一下Option的take和replace方法
    {
        let mut a = Some(188);
        println!("{:?}",a); //Some(188)
        let b = a.take();   //有,就拿走,a就变成None
        println!("{:?}",b); //Some(188)
        println!("{:?}",a); //None
        println!("{:?}",a.take());  //None
        let c = a.replace(166); //c变成a原来的值,a变成新的值
        println!("{:?}",a); //Some(166)
        println!("{:?}",c); //None
        let c = a.replace(721);
        println!("{:?}",a); //Some(721)
        println!("{:?}",c); //Some(166)
    }
    println!("---------");
    println!("{:?}",s);
    let set:BTreeSet<i32> = (1..11).map(|v|v).collect();
    println!("{:?}",set);
    println!("{}",s.is_subset(&set));   //s是否是set的子集
    println!("{}",set.is_superset(&s)); //set是否是s的超集
    println!("{}",s.is_disjoint(&set)); //有无交集,有
    let s1 = BTreeSet::from([99,98,100]);
    println!("{}",s1.is_disjoint(&set)); //有无交集,无

    s.insert(99);
    s.insert(98);
    println!("{:?}",s.difference(&s1)); //s去掉和s1相交的部分
    println!("{:?}",s1.difference(&s)); //s1去掉和s相交的部分

    //效果就像是两个集合都去掉重叠的部分,然后合并
    println!("{:?}",s.symmetric_difference(&s1));
    println!("{:?}",s1.symmetric_difference(&s));

    println!("{:?}",s.intersection(&s1));   //求交集
    println!("{:?}",s.union(&s1));    //求并集

    //清除后,就是空的了
    // s.clear();
    // println!("{}",s.is_empty());
}

5.BinaryHeap

use std::collections::BinaryHeap;
use std::cmp::Reverse;
use std::any::type_name;
//输出变量类型
fn print_type_of<T>(_: &T) {
    println!("{}", type_name::<T>());
}
fn main() {
    let mut h:BinaryHeap<i32> = BinaryHeap::new();
    let mut h = BinaryHeap::from([1,2,3,4,5]);
    let mut h:BinaryHeap<i32> = BinaryHeap::with_capacity(10);
    let mut h:BinaryHeap<i32> = (0..6).map(|v|v*2+3).collect();
    // h.push(1);   
    println!("{:?}",h.peek());    //Some(13) 只获取,不弹出
    println!("{:?}",h.pop());       //Some(13)  获取,并且弹出
    // println!("{:?}",h);

    println!("{}",h.len());
    println!("{}",h.capacity());

    //遍历都需要&,不然会带走所有权
    for x in &h {
        // print_type_of(&x);
        println!("{}",x);
    }

    println!("{}",h.is_empty());
    {
        let mut val = h.peek_mut().unwrap();    //peek_mut 可以理解成获取Option<可变引用>。 实际是 Option<PeekMut<'_, T>>
        *val = 0;   //堆顶值的变化,会导致堆的重新分配
    }
    println!("{:?}",h);

    let mut heap:BinaryHeap<i32> = BinaryHeap::from([66,67,68,69]);
    h.append(&mut heap);    //会消耗heap,导致数据清空,但是容量还在
    println!("{:?}",h);
    println!("{:?},len {} capacity {}",heap,heap.len(),heap.capacity());    //[],len 0 capacity 4

    println!("--------------");
    println!("{:?}",h.peek());
    h.retain(|v|{
        // print_type_of(&v);  //&i32
        *v<=50
    }); //对堆数据的操作,都会引起重构吧
    println!("{:?}",h.peek());

    for v in h.iter() {
        println!("{}",v);
    }
    //以清空为代价,顺序输出
    while let Some(val) = h.pop() {
        println!("{}",val);
    }

    println!("最小堆 使用Reverse或自定义排序");
    // let mut h:BinaryHeap<_> = BinaryHeap::new();
    // h.push(Reverse(1));
    // h.push(Reverse(2));
    // h.push(Reverse(3));
    //不能这样创建 value of type `BinaryHeap<i32>` cannot be built from `std::iter::Iterator<Item=Reverse<{integer}>>`
    // let h:BinaryHeap<i32> = (0..6).map(|v|Reverse(v)).collect(); 
    let mut h:BinaryHeap<_> = (0..6).map(|v|Reverse(v)).collect(); 

    println!("{:?}",h.pop());
}
posted @ 2024-10-30 21:07  念秋  阅读(17)  评论(0编辑  收藏  举报