Rust 在VEC的中间或开始时有效地插入或替换多个元素? 在线性时间中,在代码< V>代码>的中间或开始时,有没有简单的方法来插入或替换多个元素?

Rust 在VEC的中间或开始时有效地插入或替换多个元素? 在线性时间中,在代码< V>代码>的中间或开始时,有没有简单的方法来插入或替换多个元素?,rust,Rust,我只能找到,但这只是为了在O(n)time中插入一个元素,所以我显然不能在循环中调用它 我可以在该索引处进行拆分,将新元素扩展到拆分的左半部分,然后将下半部分扩展到上半部分,但是有更好的方法吗?好的,Vec接口中没有合适的方法(如我所见)。但我们可以自己实施同样的事情 memmove 当T为Copy时,最明显的方法可能是移动内存,如下所示: fn push_all_at<T>(v: &mut Vec<T>, offset: usize, s: &[T])

我只能找到,但这只是为了在
O(n)
time中插入一个元素,所以我显然不能在循环中调用它


我可以在该索引处进行
拆分
将新元素扩展到拆分的左半部分,然后
将下半部分扩展到上半部分,但是有更好的方法吗?

好的,Vec接口中没有合适的方法(如我所见)。但我们可以自己实施同样的事情

memmove 当TCopy时,最明显的方法可能是移动内存,如下所示:

fn push_all_at<T>(v: &mut Vec<T>, offset: usize, s: &[T]) where T: Copy {
    match (v.len(), s.len()) {
        (_, 0) => (),
        (current_len, _) => {
            v.reserve_exact(s.len());
            unsafe {
                v.set_len(current_len + s.len());
                let to_move = current_len - offset;
                let src = v.as_mut_ptr().offset(offset as isize);
                if to_move > 0 {
                    let dst = src.offset(s.len() as isize);
                    std::ptr::copy_memory(dst, src, to_move);
                }
                std::ptr::copy_nonoverlapping_memory(src, s.as_ptr(), s.len());
            }
        },
    }
}
fn在(v:&mut-Vec,offset:usize,s:&T])处推送所有内容,其中T:Copy{
匹配(v.len(),s.len()){
(_, 0) => (),
(当前版本)=>{
v、 保留精确(s.len());
不安全{
v、 设置_len(当前_len+s.len());
let to_move=当前长度-偏移量;
设src=v.as_mut_ptr().offset(offset as isize);
如果要移动>0{
设dst=src.offset(s.len()为isize);
std::ptr::复制_内存(dst、src、to_move);
}
std::ptr::复制非重叠内存(src,s.as_ptr(),s.len());
}
},
}
}
洗牌 如果T不是复制,但它实现了克隆,我们可以将给定的切片附加到Vec的末尾,并在线性时间内使用交换将其移动到所需的位置:

fn push_all_at<T>(v: &mut Vec<T>, mut offset: usize, s: &[T]) where T: Clone + Default {
    match (v.len(), s.len()) {
        (_, 0) => (),
        (0, _) => { v.push_all(s); },
        (_, _) => {
            assert!(offset <= v.len());
            let pad = s.len() - ((v.len() - offset) % s.len());
            v.extend(repeat(Default::default()).take(pad));
            v.push_all(s);
            let total = v.len();
            while total - offset >= s.len() {
                for i in 0 .. s.len() { v.swap(offset + i, total - s.len() + i); }
                offset += s.len();
            }
            v.truncate(total - pad);
        },
    }
}
fn在(v:&mut-Vec,mut-offset:usize,s:&T])推送所有内容,其中T:Clone+Default{
匹配(v.len(),s.len()){
(_, 0) => (),
(0,u)=>{v.push_uall(s);},
(_, _) => {
断言!(offset=s.len(){
对于0..s.len(){v.swap(偏移量+i,总计-s.len()+i);}
偏移量+=s.len();
}
v、 截断(总-垫);
},
}
}
迭代器concat 也许最好的选择是根本不修改Vec。例如,如果您打算通过迭代器访问结果,我们可以从块中构建迭代器链:

let v: &[usize] = &[0, 1, 2];
let s: &[usize] = &[3, 4, 5, 6];
let offset = 2;
let chain = v.iter().take(offset).chain(s.iter()).chain(v.iter().skip(offset));

let result: Vec<_> = chain.collect();
println!("Result: {:?}", result);
让v:&[usize]=&[0,1,2];
让我们:&[usize]=&[3,4,5,6];
设偏移量=2;
让chain=v.iter().take(offset).chain(s.iter()).chain(v.iter().skip(offset));
let结果:Vec=chain.collect();
println!(“结果:{:?}”,结果);
从Rust 1.21.0开始,提供并允许在任何点插入,包括完全预弯:

let mut vec = vec![1, 5];
let slice = &[2, 3, 4];

vec.splice(1..1, slice.iter().cloned());

println!("{:?}", vec); // [1, 2, 3, 4, 5]
文件规定:

注4:如果:

  • 尾部(向量范围后的元素)为空
  • 或者用
替换_产生的元素少于范围的长度
  • 或者其
    size\u hint()
    的下限是精确的
  • 在这种情况下,片的迭代器的下限应该是精确的,因此它应该执行一次内存移动


    splice
    功能更强大,它允许您删除一系列值(第一个参数),插入新值(第二个参数),还可以选择获取旧值(调用的结果)

    替换一组项目

    let mut vec = vec![0, 1, 5];
    let slice = &[2, 3, 4];
    
    vec.splice(..2, slice.iter().cloned());
    
    println!("{:?}", vec); // [2, 3, 4, 5]
    
    let mut vec = vec![0, 1, 2, 3, 4];
    let slice = &[9, 8, 7];
    
    let old: Vec<_> = vec.splice(3.., slice.iter().cloned()).collect();
    
    println!("{:?}", vec); // [0, 1, 2, 9, 8, 7]
    println!("{:?}", old); // [3, 4]
    
    获取以前的值

    let mut vec = vec![0, 1, 5];
    let slice = &[2, 3, 4];
    
    vec.splice(..2, slice.iter().cloned());
    
    println!("{:?}", vec); // [2, 3, 4, 5]
    
    let mut vec = vec![0, 1, 2, 3, 4];
    let slice = &[9, 8, 7];
    
    let old: Vec<_> = vec.splice(3.., slice.iter().cloned()).collect();
    
    println!("{:?}", vec); // [0, 1, 2, 9, 8, 7]
    println!("{:?}", old); // [3, 4]
    
    让mut-vec=vec![0,1,2,3,4];
    让切片=&[9,8,7];
    让old:Vec=Vec.splice(3..,slice.iter().cloned()).collect();
    println!(“{:?}”,vec);//[0,1,2,9,8,7]
    println!(“{:?}”,old);//[3,4]
    
    我试图预先编写rust中的一个向量,并发现它与此处有关联(尽管这个问题是预先编写和插入以及效率。我认为我的答案作为另一个更精确的问题的答案会更好,因为我无法证明效率),但下面的代码帮助我编写,(与此相反。)[我确信其他两个答案更有效,但从我的学习方式来看,我喜欢用示例来演示答案的应用。]

    pub-trait-Unshift{fn-Unshift(&mut-self,s:&[T])->();}
    pub-trait UnshiftVec{fn UnshiftVec(&mut-self,s:vec)->()}
    pub trait UnshiftMemoryHog{fn unshiftu memory_hog(&mut self,s:Vec)->()}
    pub-trait-Shift{fn-Shift(&mut-self)->();}
    pub-trait-ShiftN{fn-shift_n(&mut-self,s:usize)->()}
    Vec的impl移位{
    fn shift_n(&mut self,s:usize)->()
    //在哪里
    //T:std::clone::clone,
    {   
    自排水(0..s);
    }
    }
    Vec的impl移位{
    fn移位(&mut self)->()
    //在哪里
    //T:std::clone::clone,
    {   
    自排水管(0..1);
    }
    }
    为Vec执行取消移位{
    fn取消移位(&mut self,s:&T])->()
    //在哪里
    //T:std::clone::clone,
    {   
    自拼接(0..0,s.至_-vec());
    }
    }
    为Vec执行impl UnshiftVec{
    fn取消移位向量(&mut self,s:vec)->()
    哪里
    T:std::clone::clone,
    {   
    自拼接(0..0,s);
    }
    }
    Vec的impl UNSHIFTMORYHOG{
    fn取消移位存储(和多个self,s:Vec)->()
    哪里
    T:std::clone::clone,
    {
    让mut tmp:Vec=s.to_owned();
    //让mut tmp:Vec=s.clone();//这也适用于某些数据类型
    /*
    让local_s:Vec=self.clone();//显式克隆()
    tmp.extend(local_s);//到vec是可能的
    */
    extend(self.clone());
    *self=tmp;
    //*self=(*tmp).to_vec();//仅仅因为它是编译的,并不意味着它是正确的。
    }
    }
    //这适用于:v=unshift(v,&vec![8]);
    //(如果不希望为Vec执行取消移位)
    #[允许(死代码)]
    fn取消移位fn(v:Vec,s:&T])->Vec
    哪里
    T:克隆,
    {
    //创建一个可变的vec并填充它
    //用克隆的