Замена элементов среза (на месте) - PullRequest
0 голосов
/ 27 февраля 2020

Я разместил свое решение в ответах ниже.

Вопрос не будет обновлен еще большим кодом, чтобы не увеличивать беспорядок.


Я пытаюсь повернуть все элементы в Vec<Vec<T>> по часовой стрелке. Вектор гарантированно будет квадратным, как в v.len() == v[0].len().

Идея состоит в том, чтобы

  • найти все элементы, эквивалентные по симметрии вращения центру v
  • поменяйте местами эти элементы, используя std :: mem :: swap

Мой текущий код не меняет состояние ve c. Как это исправить?

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);
    }
}

Редактировать:
Исправлены незначительные проблемы в исходном коде выше, благодаря @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);
        }
    }
}

1 Ответ

0 голосов
/ 28 февраля 2020

Обмен элементов в срезе может быть выполнен с использованием метода swap() среза .

. Для решения этой проблемы код теперь выглядит следующим образом:

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);
        }
    }
}

Однако у меня возникла проблема с правильной индексацией фрагмента. Вопрос можно найти здесь:

Индексация вращательной симметрии в одномерном «квадратном» массиве

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...