《编程珠玑》第二章 “杂技算法” 和 “翻转算法” C语言实现

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


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


[cpp]  view plain copy
  1. /* 
  2. ** 
  3. **  tcpipstack @29/10/2012. 
  4. **  shenzhen. 
  5. ** 
  6. */  
  7. #include <iostream>  
  8. #include <string>  
  9.   
  10. using namespace std;  
  11.   
  12. /* Acrobat Rotate Shift Alogrithm */  
  13. string AcrobatRotateShift(string str, int n);  
  14.   
  15. //  
  16. int main(void)  
  17. {  
  18.     string str1 = "abcdefg";  
  19.     string str2 = "";  
  20.   
  21.     cout<<"str1= "<<str1<<endl;  
  22.     cout<<"str2= "<<str2<<endl;  
  23.   
  24.   
  25.     str2 = AcrobatRotateShift(str1, 2);  
  26.   
  27.     cout<<"str1= "<<str1<<endl;  
  28.     cout<<"str2= "<<str2<<endl;  
  29.   
  30.     getchar();  
  31.   
  32.     return 0;  
  33. }  
  34.   
  35.   
  36. /* 
  37. * 
  38. *   the Acrobat Rotate Shift Alogrithm 
  39. * 
  40. */  
  41. string AcrobatRotateShift(string str, int n)  
  42. {  
  43.     int strlen = str.length();  
  44.     int count = 0; //统计移动次数  
  45.     int i, j = 0; //k初始化为0,从str[0]开始  
  46.     char temp;  
  47.   
  48.     while (1)  
  49.     {  
  50.         //开始的元素保存到临时变量temp中  
  51.         temp = str[j];   
  52.         i = (j + n) % strlen;  
  53.   
  54.         //开始移动,直到遇到开始的元素  
  55.         while (i != j)   
  56.         {  
  57.             str[(i - n + strlen) % strlen] = str[i];  
  58.             count++;    //移动次数统计量+1  
  59.             i = (i + n) % strlen;  
  60.         }  
  61.   
  62.         //临时变量temp中保存的值赋值给刚才移动的最后一个位置  
  63.         str[(j - n + strlen) % strlen] = temp;  
  64.         count++;  
  65.   
  66.         //判断是否所有元素都已经移动  
  67.         if (count < strlen)      
  68.         {  
  69.             //没有移动所有元素,再次从str[j+1]开始  
  70.             j++;   
  71.         }  
  72.         else  
  73.         {  
  74.             //所有元素都已经移动,跳出循环  
  75.             break;   
  76.         }  
  77.     }  
  78.   
  79.     return str;  
  80. }  

翻转算法
我们将问题看成把数组ab转换成ba,同时假定我们拥有一个函数可以将数组中的特定部分元素求逆。从ab开始,先对a求逆,得到ar b,然后对b求逆,得到ar br  ,然后整体求逆,得到(ar br)r 。此时就是ba。

[cpp]  view plain copy
  1. /* 
  2. ** 
  3. **  tcpipstack @29/10/2012. 
  4. **  shenzhen. 
  5. ** 
  6. */  
  7. #include <iostream>  
  8. #include <string>  
  9.   
  10. using namespace std;  
  11.   
  12.   
  13. string Reverse(string str, int m, int n);  
  14. string InverseRotateShift(string str, int n);  
  15.   
  16.   
  17. //  
  18. int main(void)  
  19. {  
  20.     string str1 = "abcdefg";  
  21.     string str2 = "";  
  22.   
  23.     cout<<"str1= "<<str1<<endl;  
  24.     cout<<"str2= "<<str2<<endl;  
  25.       
  26.     str2 = InverseRotateShift(str1, 5);  
  27.   
  28.     cout<<"str1= "<<str1<<endl;  
  29.     cout<<"str2= "<<str2<<endl;  
  30.   
  31.     getchar();  
  32.   
  33.     return 0;  
  34. }  
  35.   
  36.   
  37. //  
  38. string Reverse(string str, int m, int n)  
  39. {  
  40.     char temp;  
  41.   
  42.     while (m < n)  
  43.     {  
  44.         temp = str[m];  
  45.   
  46.         str[m] = str[n];  
  47.         str[n] = temp;  
  48.   
  49.         m++;  
  50.         n--;  
  51.     }  
  52.   
  53.     return str;  
  54. }  
  55.   
  56.   
  57. string InverseRotateShift(string str, int n)  
  58. {  
  59.     int strlen = str.length();  
  60.   
  61.     str = Reverse(str, 0, n-1);  
  62.     str = Reverse(str, n, strlen-1);  
  63.     str = Reverse(str, 0, strlen-1);  
  64.   
  65.     return str;  
  66. }  

以上。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值