编程珠玑--杂技算法--字符串、数组的旋转

 

昨天面试去了,讲到字符串移动,也就是交换位置,等于是循环移动。。。结果我自己把自己给绕进去了,怎么都动不好,回来总结总结,发现原因了!

待移动的数组假设为a,长度为len,需要移动rotate位,编程珠玑上说的:用的时候,务必小心!书中给的是len =12,rotate=3,是整数倍的关系,直接可以循环3次实现移位,但是这是特殊情况,对于任意情况,应该考虑不是整数倍的时候怎么移动,举个例子:

数组0~11,一个12个数,这个比较有代表性,可以移动4,5,8次来满足各种情况,
1)对于4次,是12的的整数倍,就像书中写的那样,循环4次就可以完成,每次都刚好移完整个串,代码是这样的:

 1         for (int i = 0; i < 4; i++) {
 2             temp = a[i];
 3             before = i;
 4             while (true) {
 5                 next = (before + rotate) % len;
 6                 if (next == i) {
 7                     break;
 8                 } else {
 9                     a[before] = a[next];
10                     before = next;
11                 }
12             }
13             a[before] = temp;
14         }

每次取到等于i的时候,就从temp里取出该轮的第一个值,这是个循环,跳出,进入下一轮;
2)当移动5位的时候,不是12的整数倍,这时,会一直循环,只有到最后一个数的移动,才会使next值等于i,因为next怎么加rotate,都不会是len的整数倍,

这时,整个循环只要1次就行了,会一直在while里循环,直到最后取出temp值才会跳出,这时已经移位结束了。则这部分代码就是上面的4-->1;

3)当移动8位时,0->8->4->0此时取模后等于0,按照情况1里的描述,就会取出temp值放到4里,并结束当次循环,这个循环次数怎么控制呢,还有没有移动的数,我们发现只有0~4之间的数没有移动,这个4的由来是len和rotate的最大公约数,则首先求的最大公约数,作为循环次数:

 1 //用辗转相除来求得最大公约数
 2 public static int gcd(int a, int b) {
 3     while (a != 0) {
 4         if (a >= b)
 5             a -= b;
 6         else {
 7             int t = a;
 8             a = b;
 9             b = t;
10         }
11     }
12     return b;
13 }

再将这个最大公约数代替情况1中的4,就可实现整个移动了!

 

转载于:https://www.cnblogs.com/vtianyun/archive/2012/05/11/2495855.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值