左旋字符串——编程珠玑和STL所想到的

在看编程珠玑时候有这么一题:
将一个长为n的字符串左旋i位,例如abcdefg左旋3位得到:defgabc
在书上提到了两种解法,分别如下,习题中有这么一个问题:i和n的最大公约数如何才能被程序用到?一时间没有思路,看看STL是怎么实现的,果然用到了最大公约数。最后就介绍STL中的rotate算法。
法一:从a[0]开始,每隔i位,将后面的元素移到前面去,将a[i]移到a[0],a[2*i]移到a[i]上,若k*i大于n了,则取模。直到再次遇到a[0]时停止。这时如果还没将所有元素都移动过一遍,则从a[1]开始再次移动。
vector < int  > a;
void  rotate( vector  < int  >  a  ,  int  i  )
{
         int  totalmove = 0;     //计算移动的总步数
         for (  int  j = 0; j <  i ; j++) {
                int  p = j;      //保存将要被覆盖的点
                int  cur = (p +  i ) %  a .size();       //这一次要移动的点
                int  tmp =  a [j];        //保存第一个元素
                while  (cur != j) {
                       a [p] =  a [cur];
                     p = cur;
                     cur = (p +  i ) %  a .size();
                     totalmove++;
              }
                a [p] = tmp;     //将第一个元素放到位置
                if (totalmove ==  a .size() - 1) {            //因为少一个第一个元素的移动,所以步数减一
                       break   //全部移动过了,停止
              }
       }
         ostream_iterator < int  > oit(cout,  " " );
       copy(  a .begin(),  a .end(), oit);
       cout<<endl;
}

法二:将数组分成两个部分,mn,我们想要达到的目的是nm,则nm = (n^rm^r)^r。
void  reverse( int  m  ,  int  n  )
{
         while  (  m  <  n )
       {
                int  tmp = a[  m ];
              a[  m ] = a[  n ];
              a[  n ] = tmp;
                m ++,  n --;
       }
}

void  rotate2( vector  < int  >  a  ,  int  i  )
{
         int  r =  i  %  a .size();
       reverse(0,  i  - 1);     //reverse函数的作用是倒转指定区域的元素
       reverse(  i ,  a .size() - 1);
       reverse(0,  a .size() - 1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值