《編程珠璣》第二章 “雜技算法” 和 “翻轉算法” 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的最大公約數)次循環後,才能把每一個元素都移到該移的地方。


  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。

  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. }  

以上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章