perfect_shuffle的C++實現

今天花了點時間實現了C++版的perfect_shuffle算法,具體代碼如下:

//compiled with g++
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cassert>
using namespace std;

void cycle_leader(vector<int> &a,int from, int mod) {  
  for (int i = from * 2 % mod;i != from; i = i * 2 % mod)
     swap(a[from],a[i]);
}

void perfect_shuffle(vector<int> &a,int n){
   int n2,m,i,k,t;
   vector<int>::iterator iter = a.begin()+1; //exclude index 0
   for(;n > 1;){
      //step 1
      n2 = n * 2;
      for(k = 0,m = 1; n2 / m >=3; ++k,m *= 3)
         ;
      m /= 2;
      // 2m = 3^k - 1 , 3^k <= 2n < 3^(k + 1)

      //step 2   STL/algorithm-rotate
      rotate(iter+m, iter+n, iter+m+n ); //right cyclic shift of the index[m+1,...,n+m] O(n)
      
      //step 3
      for(i = 0,t = 1;i < k; ++i,t *= 3)
         cycle_leader(a,t,m * 2 +1);
      
      //step 4
      iter += (m * 2);
      n -= m;
   }
   //n = 1
   swap(a[1],a[2]);
}

int main(){
   vector<int > a;
   a.push_back(0);//to make index start from 1
   int num = 0,length = 0;
   cout<<"Please input your number to be shuffled and '0' to end up \n";
   cin>>num;
   while(num != 0){
      a.push_back(num);
      cin>>num;
   }
   cout<<"The input number is \n";
   copy(a.begin()+1,a.end(),ostream_iterator<int> (cout," "));
   cout<<"\n";
   
   length = a.size();
   assert(length % 2 == 1); //the size of input number is even
   perfect_shuffle(a,length / 2);
   //cycle_leader(a,1,9);
   cout<<"After shuffered,the number is  \n";
   copy(a.begin()+1,a.end(),ostream_iterator<int> (cout," "));
   cout<<"\n";
}

關鍵的算法就是cycle_leader,這是整個算法實現O(n)複雜度的功勞所在,爲了實現這個圈只需要在一個循環中不停的交換下標爲from和i(不停的更新)的元素,

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