第二章:基本的算法(1)
下面就从编程珠玑的第二章算法讲起,首先请看问题描述:
将一个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 }
这样 实现了两种旋转的算法,好了今天就到这了。