Arrays 1D中的旋转对称索引;“正方形”;排列
我有一个长度为1D的数组Arrays 1D中的旋转对称索引;“正方形”;排列,arrays,algorithm,rust,rotation,Arrays,Algorithm,Rust,Rotation,我有一个长度为1D的数组size*size,表示一个值的正方形字段。 我的目标是将阵列旋转到位()。我目前在获取内环中的正确索引时遇到问题。我的算法有什么错误 这是我的代码,请跳过下面的解释和示例 代码(1.41.0) 示例迭代步骤 示例输出 在5*5“正方形”数组上使用1D索引,以下是所有索引元组(a、b、c、d)的所需和当前输出: 所需输出|电流输出|参数 || r l i ( 0, 4, 24, 20) | ( 0, 4, 24, 20) | 0 4 0 ( 1, 9, 23,
size*size
,表示一个值的正方形字段。
我的目标是将阵列旋转到位()。我目前在获取内环中的正确索引时遇到问题。我的算法有什么错误
这是我的代码,请跳过下面的解释和示例
代码(1.41.0)
示例迭代步骤
示例输出
在5*5“正方形”数组上使用1D索引,以下是所有索引元组(a、b、c、d)的所需和当前输出:
所需输出|电流输出|参数
|| r l i
( 0, 4, 24, 20) | ( 0, 4, 24, 20) | 0 4 0
( 1, 9, 23, 15) | ( 1, 9, 23, 15) | 0 4 1
( 2, 14, 22, 10) | ( 2, 14, 22, 10) | 0 4 2
( 3, 19, 21, 5) | ( 2, 14, 22, 10) | 0 4 3
| |
(6,8,18,16)|(7,12,11,6)| 1 3该问题完全是由于在计算中使用l
引起的。
元素的位置与环、大小和索引直接相关,但与当前环上有多少唯一索引无关(l
)。这是我在原始代码中的错误
正如@Gene在评论中提到的,将i
左边的第行旋转i
步,将j
列向下旋转j
步,可以获得类似的结果。我仍然相信我下面介绍的方法有其优点,因为它可以很容易地扩展,允许对要旋转的元素元组进行任意条件检查
enum Rotation {
Clockwise,
Counterclockwise,
}
fn rotate_square_slice<T>(slice: &mut [T], s: usize, rotation: Rotation) {
// iterate ringwise, from outer to inner
// skip center when size % 2 == 1
for r in 0..s / 2 {
// for all unique indices under rotational symmetry ...
for i in 0..s - (2 * r) - 1{
// ... get their 4 corresponding positions ...
let a = s * ( r ) + r+i ;
let b = s * ( r+i ) + s-r-1 ;
let c = s * ( s-r-1 ) + s-r-i-1 ;
let d = s * (s-r-i-1) + r ;
//... and swap them in the correct direction.
match rotation {
Rotation::Clockwise => {
slice.swap(a, b);
slice.swap(a, c);
slice.swap(a, d);
},
Rotation::Counterclockwise => {
slice.swap(a, b);
slice.swap(c, d);
slice.swap(b, d);
}
}
}
}
}
枚举旋转{
顺时针方向的
逆时针方向的
}
fn旋转\平方\切片(切片:&mut[T],s:usize,旋转:旋转){
//从外到内循环
//当大小%2==1时跳过中心
对于0..s/2{
//对于旋转对称下的所有唯一指数。。。
对于0..s-(2*r)-1中的i{
//…获取他们的4个对应位置。。。
设a=s*(r)+r+i;
设b=s*(r+i)+s-r-1;
设c=s*(s-r-1)+s-r-i-1;
设d=s*(s-r-i-1)+r;
//…并按正确的方向交换。
比赛轮换{
旋转::顺时针=>{
切片交换(a,b);
切片交换(a,c);
切片交换(a,d);
},
旋转::逆时针=>{
切片交换(a,b);
切片交换(c,d);
切片交换(b,d);
}
}
}
}
}
非常感谢@Jmb!看不见树林,看不见树木
由于切片的线性布局,只需使用旋转某个Vec的子切片即可。干净利落 该问题是由于在计算中使用了l
。
元素的位置与环、大小和索引直接相关,但与当前环上有多少唯一索引无关(l
)。这是我在原始代码中的错误
正如@Gene在评论中提到的,将i
左边的第行旋转i
步,将j
列向下旋转j
步,可以获得类似的结果。我仍然相信我下面介绍的方法有其优点,因为它可以很容易地扩展,允许对要旋转的元素元组进行任意条件检查
enum Rotation {
Clockwise,
Counterclockwise,
}
fn rotate_square_slice<T>(slice: &mut [T], s: usize, rotation: Rotation) {
// iterate ringwise, from outer to inner
// skip center when size % 2 == 1
for r in 0..s / 2 {
// for all unique indices under rotational symmetry ...
for i in 0..s - (2 * r) - 1{
// ... get their 4 corresponding positions ...
let a = s * ( r ) + r+i ;
let b = s * ( r+i ) + s-r-1 ;
let c = s * ( s-r-1 ) + s-r-i-1 ;
let d = s * (s-r-i-1) + r ;
//... and swap them in the correct direction.
match rotation {
Rotation::Clockwise => {
slice.swap(a, b);
slice.swap(a, c);
slice.swap(a, d);
},
Rotation::Counterclockwise => {
slice.swap(a, b);
slice.swap(c, d);
slice.swap(b, d);
}
}
}
}
}
枚举旋转{
顺时针方向的
逆时针方向的
}
fn旋转\平方\切片(切片:&mut[T],s:usize,旋转:旋转){
//从外到内循环
//当大小%2==1时跳过中心
对于0..s/2{
//对于旋转对称下的所有唯一指数。。。
对于0..s-(2*r)-1中的i{
//…获取他们的4个对应位置。。。
设a=s*(r)+r+i;
设b=s*(r+i)+s-r-1;
设c=s*(s-r-1)+s-r-i-1;
设d=s*(s-r-i-1)+r;
//…并按正确的方向交换。
比赛轮换{
旋转::顺时针=>{
切片交换(a,b);
切片交换(a,c);
切片交换(a,d);
},
旋转::逆时针=>{
切片交换(a,b);
切片交换(c,d);
切片交换(b,d);
}
}
}
}
}
非常感谢@Jmb!看不见树林,看不见树木
由于切片的线性布局,只需使用旋转某个Vec的子切片即可。干净利落 我猜我在处理环边长度l时犯了一个错误。不过,我不能用手指去碰它。它看起来像是你在减法r
太多次了:当你计算l
时减法一次,然后每次使用它时再减法一次(如l-r
)。把你所有的l-r
换成可能是直的l
@Jmb。第一个元组的第一个值也是错误的(7而不是6),并且第一个值的公式不包含“l”。你有什么想法吗?是的:i
从r
开始,而不是从0开始。因此,您也应该将所有的i+r
替换为普通的i
(而-i-r
替换为-i
)。@Jmb谢谢。就在那里。我的错误是从0开始计算。如果我没弄错的话,你的版本几乎可以正常工作,除了案例c。我现在不在计算机附近,但稍后将尝试实施更改。非常感谢,真的!我猜我在处理环边长度l时犯了一个错误。不过,我不能用手指去碰它。它看起来像是你在减法r
太多次了:当你计算l
时减法一次,然后每次使用它时再减法一次(如l-r
)。将所有l-r
替换为
0 1 2 3 4
0 . a . . .
1 . . . . b
2 . . . . .
3 d . . . .
4 . . . c .
size = 5 | position(a) = ( r , r+i ) = (0, 1)
r = 0 | position(b) = ( r+i , l-r ) = (1, 4)
l = 4 | position(c) = ( l-r , l-r-i) = (4, 3)
i = 1 | position(d) = (l-r-i, r ) = (3, 0)
desired output | current output | parameters
| | r l i
( 0, 4, 24, 20) | ( 0, 4, 24, 20) | 0 4 0
( 1, 9, 23, 15) | ( 1, 9, 23, 15) | 0 4 1
( 2, 14, 22, 10) | ( 2, 14, 22, 10) | 0 4 2
( 3, 19, 21, 5) | ( 2, 14, 22, 10) | 0 4 3
| |
( 6, 8, 18, 16) | ( 7, 12, 11, 6) | 1 3 1 <- mistake
( 7, 13, 17, 11) | ( 8, 17, 10, 1) | 1 3 2 <- mistake
| |
enum Rotation {
Clockwise,
Counterclockwise,
}
fn rotate_square_slice<T>(slice: &mut [T], s: usize, rotation: Rotation) {
// iterate ringwise, from outer to inner
// skip center when size % 2 == 1
for r in 0..s / 2 {
// for all unique indices under rotational symmetry ...
for i in 0..s - (2 * r) - 1{
// ... get their 4 corresponding positions ...
let a = s * ( r ) + r+i ;
let b = s * ( r+i ) + s-r-1 ;
let c = s * ( s-r-1 ) + s-r-i-1 ;
let d = s * (s-r-i-1) + r ;
//... and swap them in the correct direction.
match rotation {
Rotation::Clockwise => {
slice.swap(a, b);
slice.swap(a, c);
slice.swap(a, d);
},
Rotation::Counterclockwise => {
slice.swap(a, b);
slice.swap(c, d);
slice.swap(b, d);
}
}
}
}
}