Vector 交换切片的元素(就地) 我已经在下面的答案中发布了我的解决方案。

Vector 交换切片的元素(就地) 我已经在下面的答案中发布了我的解决方案。,vector,rust,slice,Vector,Rust,Slice,这个问题将不会更新更多的代码,以避免进一步增加混乱 我试图顺时针旋转Vec中的所有元素。 向量保证为正方形,如v.len()==v[0].len()中所示 我们的想法是 找到所有在旋转对称下等效于的元素 v的中心 使用std::mem::swap将这些元素交换到位 我的当前代码不会更改vec的状态。我该如何解决这个问题 fn rotate<T>(v: &mut Vec<Vec<T>>) { // swap elements equiva

这个问题将不会更新更多的代码,以避免进一步增加混乱


我试图顺时针旋转
Vec
中的所有元素。 向量保证为正方形,如
v.len()==v[0].len()
中所示

我们的想法是

  • 找到所有在旋转对称下等效于的元素
    v
    的中心
  • 使用std::mem::swap将这些元素交换到位
我的当前代码不会更改vec的状态。我该如何解决这个问题

fn rotate<T>(v: &mut Vec<Vec<T>>) {

    // swap elements equivalent to position i on each ring r 
    // limit l = side length of current ring
    //
    // + 0 - - - - +   r = 0 -> l = 6
    // | + 1 - - + |   r = 1 -> l = 4
    // | | + 2 + | |   r = 2 -> l = 2
    // | | |   | | |
    // | | + - + | |   swap:
    // | + - - - + |     a b c d
    // + - - - - - +   > b a c d
    //                 > c a b d
    //                 > d a b c

    for r in 0..((v.len() + 1) / 2 {
        let l = v.len() - 1 - r;
        for i in r..l {
            let mut a = & pieces[  r  ][ r+i ];
            let mut b = & pieces[ r+i ][ l-r ];
            let mut c = & pieces[ l-r ][l-r-i];
            let mut d = & pieces[l-r-i][  r  ];

            _rot_cw(&mut a, &mut b, &mut c, &mut d)},
        }
    }

    fn _rot_cw<T>(a: &mut T, b: &mut T, c: &mut T, d: &mut T) {
        //rotates a->b, b->c, c->d, d->a
        std::mem::swap(a, b);
        std::mem::swap(a, c);
        std::mem::swap(a, d);
    }
}
fn旋转(v:&mut向量){
//交换相当于每个环r上位置i的元件
//极限l=电流环的边长
//
//+0---+r=0->l=6
//|+1---+|r=1->l=4
//| |+2+| | r=2->l=2
// | | |   | | |
//| |+-+| |交换:
//|+--+| a b c d
//+->b a c d
//>c a b d
//>d a b c
对于0中的r.((v.len()+1)/2{
设l=v.len()-1-r;
因为我在r.l{
设mut a=&pieces[r][r+i];
设mut b=&个[r+i][l-r];
设mut c=&pieces[l-r][l-r-i];
设mut d=&pieces[l-r-i][r];
_旋转(旋转a、旋转b、旋转c、旋转d)},
}
}
fn_rot_cw(a:&mut T T,b:&mut T T,c:&mut T T,d:&mut T T){
//旋转a->b,b->c,c->d,d->a
std::mem::swap(a,b);
std::mem::swap(a,c);
std::mem::swap(a,d);
}
}
编辑:
由于@Jmb,修复了上面原始代码中的小问题。 以下是我当前的代码,再次遇到借用问题:

fn rotate_square_slice<T>(slice: &mut Vec<T>, rows: usize) {
    for r in 0..(slice.len()+1)/2 {
        let l = slice.len() -1 - r;
        for i in r..l {
            let a = &mut slice.get_mut(rows *    r    +  r+i ).unwrap();
            let b = &mut slice.get_mut(rows *  (r+i)  +  l-r ).unwrap();
            let c = &mut slice.get_mut(rows *  (l-r)  + l-r-i).unwrap();
            let d = &mut slice.get_mut(rows * (l-r-i) +   r  ).unwrap();

            std::mem::swap(a, b);
            std::mem::swap(a, c);
            std::mem::swap(a, d);
        }
    }
}
fn旋转\u正方形\u切片(切片:&mut向量,行:usize){
对于0..(slice.len()+1)/2中的r{
设l=slice.len()-1-r;
因为我在r.l{
让a=&mut切片。get_mut(行*r+r+i)。unwrap();
设b=&mut切片。get_mut(rows*(r+i)+l-r)。unwrap();
让c=&mut切片。get_mut(rows*(l-r)+l-r-i)。unwrap();
设d=&mut slice.get_mut(rows*(l-r-i)+r.unwrap();
std::mem::swap(a,b);
std::mem::swap(a,c);
std::mem::swap(a,d);
}
}
}
交换片中的元素可以通过使用来完成。 为了解决这个问题,代码现在如下所示:

fn rotate_square_slice<T>(slice: &mut [T], size: usize) {
    for r in 0..(size + 1) / 2 {
        let l = size - 1 - r;
        for i in r..l {    
            // b, c & d are the indices with rotational symmetry to a,
            // shifted by 90°, 180° & 270° respectively
            
            let a = size *    r    +  r+i ;
            let b = size *  (r+i)  +  l-r ;
            let c = size *  (l-r)  + l-r-i;
            let d = size * (l-r-i) +   r  ;

            slice.swap(a, b);
            slice.swap(a, c);
            slice.swap(a, d);
        }
    }
}
fn旋转正方形切片(切片:&mut[T],大小:usize){
对于0..(尺寸+1)/2中的r{
设l=尺寸-1-r;
对于r..l{
//b,c&d是对a具有旋转对称性的指数,
//分别移动90°、180°和270°
设a=尺寸*r+r+i;
设b=尺寸*(r+i)+l-r;
设c=尺寸*(l-r)+l-r-i;
设d=尺寸*(l-r-i)+r;
切片交换(a,b);
切片交换(a,c);
切片交换(a,d);
}
}
}
但是,我遇到了一个关于正确索引切片的问题。问题可以在这里找到:


请不要在
\uu
中使用的标识符前加前缀。这表示标识符必须存在,但未使用该值,这对于
\urot\ucw
&pieces
不正确。您正在对向量中的项进行不可变的引用。因为它是不可变的,所以向量不会发生变异。@Shepmaster不是这里是内部函数的另一个惯用法?或者它们通常没有标记为这样,因为它们没有公开?我有两个旁注。首先,将正方形矩阵表示为
Vec
并不理想。这种类型表示可变长度向量中的可变长度向量,您必须手动维护每个内部向量与外部向量具有相同的长度。此外,还有相当大的开销,因为您需要为每行单独分配,元素访问需要多个指针间接。使用包装单个向量的自定义类型可以为您提供更好的类型安全性和性能。第二,如果您实现平方matrix作为一种自定义类型,您将拥有自定义索引操作。这允许您为矩阵的两个轴引入两个,再加上一些固定偏移量。旋转矩阵将变成修改步幅和固定偏移量的问题,而不是实际移动所有数据。我不知道您的确切用例,因此我不知道这将非常适合您,但这是一种在实践中证明非常有用的常用方法。