zoukankan      html  css  js  c++  java
  • n维向量旋转(循环移位)——学习《编程珠玑》

    问题:

    将一个n元一维向量向左旋转i个位置。例如,当n=8且i=3时,向量abcdefgh旋转为defghabc。

    简单的代码使用一个n元的中间向量在n步内完成该工作。

    你能否仅使用数十个额外字节的存储空间,在正比于n的时间内完成向量的旋转?

    解法:

    1. 将x的前i个元素复制到一个临时数组中,然后将剩下的n-i个元素向左移动i个位置,最后将最初的i个元素从临时数组中复制到x中余下的位置。——使用i个额外位置产生过大的存储空间消耗;
    2. 定义一个函数将x向左旋转一个位置,时间正比于n,然后调用该函数i次。——产生过多的运行时间消耗;
    3. 精巧算法:移动x[0]到临时变量t,然后移动x[i]至x[0],x[2i]至x[i],以此类推(将x中的所有下标对n取模),直至返回到取x[0]中的元素,此时改为从t取值然后终止过程。如果该过程没有移动全部元素,就从x[1]开始再次进行移动,直到所有元素都已移动位置。——不需要大量存储空间,时间复杂度为n;
    4. 二分法:旋转向量x实际上就是交换向量ab的两段,获得ba。这里a代表x的前i个元素。假如a比b短,将b分为b_l和b_r两段,使得b_r具有与a相同的长度。交换a和b_r,也就是将ab_lb_r转换成b_rb_la。序列a此时已处于最终位置,现在问题变为交换b_rb_l两部分,该问题与原问题具有相同的形式,因此可以递归求解。
    5. 翻转法:假定我们拥有一个函数可以将数组中特定部分求逆。从ab开始,首先对a求逆,得到a^rb,然后对b求逆,得到a^rb^r。最后整体求逆得到(a^rb^r)^r,此时正好是ba。于是我们得到以下用于旋转的代码:
      reverse(0, i - 1)
      reverse(i, n - 1)
      reverse(0, n - 1)
      
    千里之行,始于足下~
  • 相关阅读:
    win7下的vxworks总结
    ubuntu 无法获得锁 /var/lib/dpkg/lock
    项目中用到了的一些批处理文件
    win7下安装 WINDRIVER.TORNADO.V2.2.FOR.ARM
    使用opencv统计视频库的总时长
    January 05th, 2018 Week 01st Friday
    January 04th, 2018 Week 01st Thursday
    January 03rd, 2018 Week 01st Wednesday
    January 02nd, 2018 Week 01st Tuesday
    January 01st, 2018 Week 01st Monday
  • 原文地址:https://www.cnblogs.com/wm123/p/5487834.html
Copyright © 2011-2022 走看看