《编程之美》读书笔记09: 2.17 数组循环移位

 

对长度为n的数组(ab)左移k位,最直接的方法,就是用stl的rotate函数(stl针对三种不同的迭代器,提供了三个版本的rotate)。但在某些情况下,用stl的rotate效率极差。

对数组循环,可以采用的方法有:

     动态分配一个同样长度的数组,将数据复制到该数组并改变次序,再复制回原数组。

     利用ba=(br)r(ar)r=(arbr)r,通过三次反转字符串。

③ 分组交换(尽可能使数组的前面连续几个数为所要结果):

若a长度大于b,将ab分成a0a1b,交换a0和b,得ba1a0,只需再交换a1 和a0

若a长度小于b,将ab分成ab0b1,交换a和b0,得b0ab1,只需再交换a和b0

通过不断将数组划分,和交换,直到不能再划分为止。分组过程与求最大公约数很相似。

④ 所有序号为 (i+t*k) % n (i为指定整数,t为任意整数),会构成一个循环链(共有gcd(n,k)个,gcd为n、k的最大公约数),每个循环链上的元素只要移动一个位置即可,总共交换了n次。

stl的rotate的三种迭代器,分别使用了后三种方法。

多数情况下,前三种方法效率都比较高,第一种方法过分要求内存,第四种方法,元素间平均交换次数最少,理论上效率应该是最高的,但在n和k都很大时,其效率相当差(由于每次交换访问的内存不连续,在n和k比较大时,内存访问开销很大,因为cache line命中率很低,又不断跨页访问内存。)。方法三的平均交换次数要少于方法二,但判断次数相对要多,效率相差不是太大,在大数组时方法三效率比较高,但同一个小数组左移几十万次,方法二效率略高,毕竟整个数组都可以被cache,内存访问开销小,判断次数对效率影响较大。

 

相关文章:

  • 2021-08-22
  • 2021-08-30
  • 2021-05-29
  • 2021-06-09
  • 2021-11-15
  • 2021-05-31
猜你喜欢
  • 2021-11-03
  • 2021-12-09
  • 2021-05-28
  • 2022-12-23
  • 2021-09-12
  • 2021-09-25
  • 2021-06-16
相关资源
相似解决方案