Advertisement

p363:rotate的random access iterator版本是怎么一回事?

阅读量:

旋转操作本质上等同于左移操作。例如要求将一个序列的前m个元素与后面的元素进行交换,则等价于将整个序列的所有元素向左移动m位;若移动到了头部,则会自动跳至尾部继续移动。

对于该算法而言,在每一阶段的操作包括两个步骤:首先将第i个元素赋值为第(i + m)个元素的值;接着将位于(i + m)位置的元素赋值为(i + 2m)位置的值。需要注意的是,在实现该算法时需要采用取模运算来处理索引溢出问题。这等价于整个数组向左移动m个位置。

然而存在一个问题:例如考虑数组 [a, b, c, d, e, f] , 其要求是对所有元素进行左移两位的操作。为此我们需要从起始点设为 i=0 开始执行循环操作:首先将变量 i 赋值为 0;接着将 i 跳转至位置 2;随后移动至位置 4;此时系统会自动返回至初始位置 0 进行循环往复的操作(如图 2 所示)。经过完成整个流程后发现:结果仅实现了对奇数索引元素(即 a, c, e) 的重新排列,并未对偶数索引元素(即 b, d, f) 进行任何操作

存在这样一个数学定理:当n和m的最大公约数为d时,在模运算中不断累加m并对n取余所得的序列(即:0%n、m%n、2m%n、3m%n…(n-1)m%n),实际上即为由等差数组成的序列:0,d,2d,…直到达到(n-d),并不断重复出现。例如取m=6,n=8,则它们的最大公约数为2;此时上述序列将依次变为:0→6→4→2→(继续循环)…直至重复两次后结束。

6.经过4的讨论,我们知道了为什么会出现3里面的这种问题。

假设数组元素共计n=567890123456789012345678901234567890123456789012345678901234567890123456789×(n−i)个,则令变量i`从初始下标`i=0`开始循环,则变量i能够访问的下标依次为$m×i mod~n~(i=0,1,2,…,n−1)$。其中$d=\gcd(m,n)$为$m~和~n的最大公约数,在第4部分中已详细讨论过此类情况下的遍历特性。若将变量$i完成一次循环视为一个完整周期,则在该周期内所有被访问过的索引均满足条件(j−i) \% m = 0~(j=当前索引值)的关系式成立。因此,在此情况下所有未被访问过的索引j`均满足(j−i) % m ≠ 0~的关系式成立

因此我们可以运用for循环,在变量i的取值范围从0开始一直到d-1的情况下,依次执行多个循环周期。从而确保每个索引位置都被完整覆盖,并实现整体向左的数据迁移。

全部评论 (0)

还没有任何评论哟~