下面就从编程珠玑的第二章算法讲起,首先请看问题描述:

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

简单的代码可以使用一个n元的中间变量在n步内完成工作,下面介绍一些更简便的算法。

1:杂技算法:

  移动x[0]到临时变量t,然后移动x[i]到x[0],x[2i]到x[i],依次类推(将x中的所有下标对n取模),直到返回到取x[0]值的元素,此时改为从t取值然后终止过程,当i为3时n为12时,元素安如下顺序进行移动:

 
(此代码用到了求最大公约数的算法)
 
复制代码
 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 //求最大公约数
 6 //欧几里得算法
 7 int gcd(int a, int b)
 8 {
 9     while( a!= b)
10     {
11         if(a>b) 
12         {    
13          a-=b;
14         }
15         
16         else 
17         {
18             b-=a;
19         }
20     }
21     return a
22         ;
23 }
24 
25 //杂技算法
26 void Rotate1(char* a,int lenth,int rotateLen)
27 {
28     int gcdNum = gcd(lenth,rotateLen);//字符串的长度和旋转次数的最大公约数是所需的置换数
29     
30     for(int i=0; i<gcdNum; i++)
31     {
32         char temp = a[i];
33         int first = i;
34         while(true)
35         {
36             int second = (first+rotateLen)% lenth;
37             
38             if(second == i) break;
39             
40             a[first] = a[second];
41             
42             first = second;
43         }
44         a[first] = temp;
45     }
46 }
47 
48 
49 int main()
50 {
51     char a[9] = "abcdefgh";
52     Rotate1(a,8,3);
53     cout<<a<<endl;
54     return 0;
55 }
复制代码
 
 
2:求逆算法
 
求解过程:我们将问题看做是把数组ab转换成数组ba
将a[n]看做是向量BC组成,最终的结果需要时CB,过程如下:将BC各分别取逆B^-1C^-1,再对整个式子取逆,得到CB
 
复制代码
 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     cout<<a;
30 }
复制代码

这样 实现了两种旋转的算法,好了今天就到这了。