转:编程珠玑--旋转算法

旋转算法出自《编程珠玑》第二章题目。

 

《编程珠玑》一书对算法是极度推崇,这点意识在我们看书的时候每每都有被灌输。使用一种好的算法往往能使得程序更加漂亮,也很能带给我们程序员某种满足感。

 

题目:将一个n元一维数组a[n]左移i个位置。例如,当n=8,i=3时,数组abcdefgh旋转为defghabc。请设计一个算法完成这个任务。

 

1. 块交换法

分析:将n元一维数组a[n]分解为两块,将第一块存储在临时数组中,将第二块前移i个单位,再将临时数组加入到第二块后面。

 

如:n=8,i=3时,将第一块abc存储为临时变量,第二块defgh前移3个单位,再将abc放入到defgh后面。

 

思考:这种方法最大的缺陷至少需要与两块中较小的一块大小的临时变量。

 

2.杂技算法

分析:将a[0]存储在一个临时变量中,然后将a[i]替换a[0],a[2i]替换a[i]….当一个循环结束的时候,若替换次数小于n,则从a[1]开始替换…,需要经过gcd(n,i)(n和i的最大公约数)次循环后,才能把每一个元素都移到该移的地方。

求逆算法

 

下面是代码实现:

杂耍算法代码
 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 //求最大公约数
 6 //辗转相除法
 7 int gcd(int a, int b)
 8 {
 9     while( a!= 0)
10     {
11         if(a>=b) a-=b;
12         else 
13         {
14             int t=a;
15             a=b;
16             b=t;
17         }
18     }
19     return b;
20 }
21 
22 //杂技算法
23 void Rotate1(char* a,int lenth,int rotateLen)
24 {
25     int gcdNum = gcd(lenth,rotateLen);
26     for(int i=0; i<gcdNum; i++)
27     {
28         int temp = a[i];
29         int first = i;
30         while(1)
31         {
32             int second = (first+rotateLen)% lenth;
33             if(second == i) break;
34             a[first] = a[second];
35             first = second;
36         }
37         a[first] = temp;
38     }
39 }
40 
41 
42 int main()
43 {
44     char a[9] = "abcdefgh";
45     Rotate1(a,8,3);
46 }

 

 

3. 求逆算法

分析:将a[n]看做是向量BC组成,最终的结果需要时CB,过程如下:将BC各分别取逆B^-1C^-1,再对整个式子取逆,得到CB。

 

举例:将abcdefgh中的abc看做向量B,defgh看做向量C。

 

下面是代码实现:

 

翻手算法代码
 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 void Revert(char* str,int start,int end)
 6 {
 7     while(start<end)
 8     {
 9         char temp = str[start];
10         str[start] = str[end];
11         str[end] = temp;
12         start++;
13         end--;
14     }
15 }
16 
17 void Rotate1(char* a,int start,int end)
18 {
19     Revert(a,0,2);
20     Revert(a,3,7);
21     Revert(a,0,7);
22 }
23 
24 
25 int main()
26 {
27     char a[9] = "abcdefgh";
28     Rotate1(a,0,7);
29 }

 

 

思考题:写一个算法实现字符串反转,将abc.sina.com反转为com.sina.abc。

 

分析:使用求逆算法,将abc,sina,com作为子串进行反转,再将整个字符串进行反转

 

作者:Nick Ye(yjf512)
出处:(http://www.cnblogs.com/yjf512/
版权声明:本文的版权归作者与博客园共有。欢迎转载阅读,转载时须注明本文的详细链接。 

 

参考文档:

编程珠玑(第二版)

posted @ 2012-05-16 11:47  起苏桃子  Views(189)  Comments(0Edit  收藏  举报