青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

/*
  Name: 向量旋轉算法集錦
  Copyright: 始發于goal00001111的專欄;允許自由轉載,但必須注明作者和出處
  Author: goal00001111
  Date: 28-12-08 23:28
  Description:
  向量旋轉算法:將具有n個元素的向量a向左旋轉r個位置。
  例如 :將字符串"abcdefghij"旋轉成"defghjabc",其中n=10,r=3。
  其實就是將 AB 轉換成 BA 的過程,這里A ="abc", B="defghij"。
  本文總共采用了四種方法來解決向量旋轉問題,依次是:
  方法一:最簡單的直接移動向量旋轉算法;
  方法二:簡明的的逆置數組旋轉算法;
  方法三:傳說中的雜耍旋轉算法;
  方法四:一個類似于歐幾里得算法的旋轉算法;
  其中方法一需要一個輔助數組,空間復雜度較高;方法二每個元素都要移動兩次,效率相對較低;
  方法三和方法四都是極牛的算法,空間和時間復雜度都很低。
  這是牛書《編程珠璣》中的一個例題,在書的網站上有詳細的源碼,我把它改成了我所熟悉的樣子。
  源碼的網站是:http://www.cs.bell-labs.com/cm/cs/pearls/code.html
*/
#include<iostream>
#include <time.h>

using namespace std;

template <class T> //最簡單的直接移動向量旋轉算法
void SlideRotate(T a[], int n, int r);

template <class T> //逆置數組的原子操作
void Reverse(T a[], int left, int right);

template <class T> //簡明的的逆置數組旋轉算法
void ReverseRotate(T a[], int n, int r);

int Gcd(int m, int n); //歐幾里德算法求最大公約數

template <class T> //傳說中的雜耍旋轉算法
void JuggleRotate(T a[], int n, int r);

template <class T> //交換兩個長度均為len的向量塊a[left_1..left_1+len) 和 a[left_2..left_2+len)
void Swap(T a[], int left_1, int left_2, int len);

template <class T> //一個類似于歐幾里得算法的旋轉算法
void GcdRotate(T a[], int n, int r);

template <class T> //創建一個向量
void InitVector(T a[], int n);

template <class T> //輸出一個向量
void PrintVector(const T a[], int n);

template <class T> //判斷向量旋轉是否成功
bool CheckRotate(const T a[], int n, int r);

int main()
{
    const int N = 601; //測試次數
    const int MAX = 500000; //向量長度
    int a[MAX] = {0};
    int rotateDistance = 100000;
    time_t startTime, endTime;
    
   ////////最簡單的直接移動向量旋轉算法///////////////////////////////  
    time(&startTime);
    InitVector(a, MAX);
   // PrintVector(a, MAX);
    for (int i=0; i<N; i++)
        SlideRotate(a, MAX, rotateDistance);
  //  PrintVector(a, MAX);
    if (CheckRotate(a, MAX, rotateDistance))
        cout << "True" << endl;
    else
        cout << "False" << endl;
       
    time(&endTime);
    cout << "time = " << difftime(endTime, startTime) << endl << endl;
    ///////////////////////////////////////////////////////////////////////////////////////////
    //////////簡明的的逆置數組旋轉算法//////////////////////////////////////////////////  
    time(&startTime);
    InitVector(a, MAX);
  //  PrintVector(a, MAX);
    for (int i=0; i<N; i++)
        ReverseRotate(a, MAX, rotateDistance);
  //  PrintVector(a, MAX);
    if (CheckRotate(a, MAX, rotateDistance))
        cout << "True" << endl;
    else
        cout << "False" << endl;
       
    time(&endTime);
    cout << "time = " << difftime(endTime, startTime) << endl << endl;
    ///////////////////////////////////////////////////////////////////////////////////////////
    ////////////傳說中的雜耍旋轉算法 //////////////////////////////////////  
    time(&startTime);
    InitVector(a, MAX);
  //  PrintVector(a, MAX);
    for (int i=0; i<N; i++)
        JuggleRotate(a, MAX, rotateDistance);
  //  PrintVector(a, MAX);
    if (CheckRotate(a, MAX, rotateDistance))
        cout << "True" << endl;
    else
        cout << "False" << endl;
       
    time(&endTime);
    cout << "time = " << difftime(endTime, startTime) << endl << endl;
    ///////////////////////////////////////////////////////////////////////////////////////////
    /////////////一個類似于歐幾里得算法的旋轉算法///////////////////////////////////  
    time(&startTime);
    InitVector(a, MAX);
  //  PrintVector(a, MAX);
    for (int i=0; i<N; i++)
        GcdRotate(a, MAX, rotateDistance);
  //  PrintVector(a, MAX);
    if (CheckRotate(a, MAX, rotateDistance))
        cout << "True" << endl;
    else
        cout << "False" << endl;
       
    time(&endTime);
    cout << "time = " << difftime(endTime, startTime) << endl << endl;
    ///////////////////////////////////////////////////////////////////////////////////////////
       
    system("pause");
    return 0;
}

////////////方法一:創建一個長度為min{r, n-r)的輔助數組,以幫助完成旋轉任務//////////////////
/*
函數名稱:SlideRotate
函數功能:最簡單的直接移動向量旋轉算法:先利用一個輔助數組將較短的那一段元素存儲起來,
          再移動原向量中未另外存儲的那部分元素,最后將輔助數組中的元素再復制到正確位置
輸入參數:T a[]:需要被旋轉的向量
          int n:向量的長度
          int r:向量左半段長度
輸出參數:T a[]:旋轉后的向量
返回值:無
*/
template <class T>
void SlideRotate(T a[], int n, int r)
{   
    if (r < n - r) //如果左半段小于右半段,存儲左半段的元素
    {
        T *buf = new T[r];
        for (int i=0; i<r; i++)//存儲左半段的元素
            buf[i] = a[i];
           
        for (int i=r; i<n; i++)//移動右半段的元素
            a[i-r] = a[i];
       
        for (int i=0; i<r; i++)//復制左半段的元素到右半段
            a[n-r+i] = buf[i];
       
        delete []buf; 
    }
    else //否則存儲右半段的元素 
    {
        T *buf = new T[n-r];
        for (int i=r; i<n; i++)//存儲右半段的元素
            buf[i-r] = a[i];
           
        for (int i=r-1; i>=0; i--)//移動左半段的元素
            a[i+n-r] = a[i];
       
        for (int i=0; i<n-r; i++)//復制右半段的元素到左半段
            a[i] = buf[i];
       
        delete []buf;
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////方法二:使用一個逆置數組的原子操作////////////////////////////////////
/*
函數名稱:Reverse
函數功能:逆置數組的原子操作
輸入參數:T a[]:需要被逆置的向量 
          int left: 數組的左界
          int right:數組的右界
輸出參數:T a[]:逆置后的數組
返回值:無
*/
template <class T>
void Reverse(T a[], int left, int right)
{   
    T t;
    while (left < right)
    {
        t = a[left];
        a[left] = a[right];
        a[right] = t;
        left++;
        right--;
    }
}

/*
函數名稱:ReverseRotate
函數功能:簡明的的逆置數組旋轉算法:構造一個逆置數組的原子操作子函數,然后設置不同的數組左右界,
          分三次調用子函數就行了。因為每個元素都需要移動兩次,所以效率不是很高。
輸入參數:T a[]:需要被旋轉的向量
          int n:向量的長度
          int r:向量左半段長度
輸出參數:T a[]:旋轉后的向量
返回值:無
*/
template <class T>
void ReverseRotate(T a[], int n, int r)
{   
    Reverse(a, 0, r-1); //逆置左半段數組
    Reverse(a, r, n-1); //逆置右半段數組
    Reverse(a, 0, n-1); //逆置整段數組
}
////////////////////////////////////////////////////////////////////////////////////////////////
//////////////方法三:傳說中的雜耍旋轉算法////////////////////////////////////////////////

/*
函數名稱:Gcd
函數功能:歐幾里德算法求最大公約數
輸入參數:int m:正整數之一
          int n:正整數之二
輸出參數:無
返回值:正整數m和n的最大公約數
*/
int Gcd(int m, int n)
{   
    int t;
    while (m > 0)
    {
        t = n % m;
        n = m;
        m = t;
    }
    return n;
}

/*
函數名稱:JuggleRotate
函數功能:傳說中的雜耍旋轉算法:
          先將a[0]存儲到臨時變量t中,然后將a[r]移動到a[0],將a[2r] 移動到 a[r],
          依此類推(數組中所有的下標都要對數組的長度n取模),直到(k*r)%n == 0,
          此時我們不能在a[0]中取數,而是在臨時變量t中取數,然后結束該過程。
          如果該過程不能移動所有的元素,那么我們從a[1]開始移動,一直依次下去,
          直到移動了所有的元素為止。
          那么總共要重復開始移動幾次呢?數學證明是Gcd(r, n)次。
          此算法每個元素只需移動一次就可以到達正確位置,理論上效率是最高的,
          但由于要做求最大公約數和求余運算等準備工作,所以沒有顯示出優勢。
輸入參數:T a[]:需要被旋轉的向量
          int n:向量的長度
          int r:向量左半段長度
輸出參數:T a[]:旋轉后的向量
返回值:無
*/
template <class T>
void JuggleRotate(T a[], int n, int r)
{   
    int i, j, k;
    int cyc = Gcd(r, n); //用r和n的最大公約數作為循環周期
   
    for (i=0; i<cyc; i++) //總共需要重復開始移動cyc次,才能使得所有的元素都移動到正確位置
    {
        T t = a[i]; //臨時變量t存儲a[i]
        j = i;
        while (1)//依次移動元素,直到 (k*r)%n == 0
        {
            k = j + r;
            if (k >= n) //用除法運算替代模運算
                k -= n;
               
            if (k == i)
                break;
            a[j] = a[k];
            j = k;
        }
        a[j] = t;
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////
//////////////方法四:一個類似于歐幾里得輾轉相除算法的旋轉算法/////////////////////////////////
/*
函數名稱:Swap
函數功能:交換兩個長度均為len的向量塊a[left_1..left_1+len) 和 a[left_2..left_2+len)
輸入參數:T a[]:需要被處理的向量
          int left_1:向量塊a[left_1..left_1+len)的左界
          int left_2:向量塊a[left_2..left_2+len)的左界
          int len: 兩個向量塊的長度
輸出參數:T a[]:交換了部分元素的向量
返回值:無
*/
template <class T>
void Swap(T a[], int left_1, int left_2, int len)
{   
    T t;
    while (len > 0)
    {
        t = a[left_1];
        a[left_1] = a[left_2];
        a[left_2] = t;
        left_1++;
        left_2++;
        len--;
    }
}

/*
函數名稱:JuggleRotate
函數功能:一個類似于歐幾里得輾轉相除算法的旋轉算法:
          就像一個做阻尼振動的彈簧振子一樣,按照由兩邊到中間的順序,整段的交換向量塊,
          并且被交換的向量塊長度不斷縮減,直到lLen == rLen。
          由于重復移動的元素較少,所以效率比逆置數組旋轉算法要高。
輸入參數:T a[]:需要被旋轉的向量
          int n:向量的長度
          int r:向量左半段長度
輸出參數:T a[]:旋轉后的向量
返回值:無
*/
template <class T>
void GcdRotate(T a[], int n, int r)
{   
    if (r == 0 || r == n) //特殊情況不用旋轉
        return;
   
    int lLen, rLen, pos;   
    lLen = pos = r;
    rLen = n - r;
    while (lLen != rLen)
    {
        if (lLen > rLen) //左半段大于右半段,移動右半段
        {
            Swap(a, pos-lLen, pos, rLen);
            lLen -= rLen; //減少移動范圍
        }
        else
        {
            Swap(a, pos-lLen, pos+rLen-lLen, lLen);
            rLen -= lLen;
        }
    }
    Swap(a, pos-lLen, pos, lLen); //最后交換中間段
}
////////////////////////////////////////////////////////////////////////////////////////////////
/*
函數名稱:InitVector
函數功能:創建一個向量
輸入參數:T a[]:需要被賦值的向量
          int n:向量的長度
輸出參數:T a[]:創建好的向量
返回值:無
*/
template <class T>
void InitVector(T a[], int n)
{
    for (int i=0; i<n; i++) //創建一個向量
        a[i] = i;
}

/*
函數名稱:PrintVector
函數功能:輸出一個向量
輸入參數:const T a[]:需要被輸出的向量
          int n:向量的長度
輸出參數:無
返回值:無
*/
template <class T>
void PrintVector(const T a[], int n)
{
    for (int i=0; i<n; i++)
        cout << a[i] << ' ';
    cout << endl;  
}

/*
函數名稱:CheckRotate
函數功能:判斷向量旋轉是否成功
輸入參數:T a[]:需要被旋轉的向量
          int n:向量的長度
          int r:向量左半段長度
輸出參數:無
返回值:旋轉成功返回true,否則返回false
*/
template <class T>
bool CheckRotate(const T a[], int n, int r)
{   
    for (int i=0; i<n-r; i++) //判斷左半段
    {
        if (a[i] != i+r)
            return false;
    }
   
    for (int i=0; i<r; i++)//判斷右半段
    {
        if (a[n-r+i] != i)
            return false;
    }
   
    return true;
}


Posted on 2008-12-29 12:36 夢想飛揚 閱讀(761) 評論(0)  編輯 收藏 引用
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美一区二区三区免费视频| 欧美精品一区二区三区一线天视频 | 久热爱精品视频线路一| 亚洲午夜女主播在线直播| 一本色道久久88综合亚洲精品ⅰ| 99视频精品全国免费| 一区二区三区日韩在线观看| 亚洲一区二区四区| 欧美专区在线| 欧美韩日一区二区| 国产精品日韩一区二区| 国产午夜精品在线观看| 在线日韩日本国产亚洲| 9人人澡人人爽人人精品| 午夜精品一区二区三区四区| 久久久精品网| 亚洲国产欧美国产综合一区| 欧美激情一二三区| 国产精品99久久久久久久vr| 欧美一二三视频| 欧美国产综合视频| 国产日韩欧美精品综合| 亚洲免费一级电影| 美国十次了思思久久精品导航| 亚洲国产综合视频在线观看| 亚洲乱码国产乱码精品精| 亚洲视频在线观看视频| 久久久蜜桃精品| 夜夜狂射影院欧美极品| 久久字幕精品一区| 国产精品视频久久久| 亚洲人成免费| 久久久久一区二区三区| 夜久久久久久| 欧美高清视频免费观看| 国产一本一道久久香蕉| 亚洲一二三区精品| 亚洲成色777777女色窝| 欧美在现视频| 国产美女高潮久久白浆| 在线视频日本亚洲性| 亚洲成人直播| 噜噜噜躁狠狠躁狠狠精品视频| 国产精品一二三| 一区二区三区四区五区精品| 免费成人在线观看视频| 欧美一区成人| 国产精品一级| 香蕉成人久久| 在线亚洲免费| 欧美视频在线观看一区二区| 亚洲精品网址在线观看| 欧美高清在线一区| 久久精品女人| 含羞草久久爱69一区| 久久精品亚洲精品国产欧美kt∨| 一区二区三区四区国产| 欧美视频久久| 亚洲欧美久久| 亚洲午夜久久久久久尤物| 欧美三级第一页| 日韩一区二区免费高清| 亚洲精品日韩综合观看成人91| 久久中文字幕导航| 亚洲国产一区在线观看| 亚洲高清在线| 欧美激情综合亚洲一二区| 99国产精品99久久久久久粉嫩| 亚洲人成绝费网站色www| 欧美精品一区二区三区高清aⅴ| 一本久道久久综合婷婷鲸鱼| 91久久在线视频| 欧美日韩一区二区三区免费| 国产精品99久久不卡二区| 日韩视频一区| 国产精品―色哟哟| 久久一区国产| 欧美劲爆第一页| 亚洲中字在线| 久久xxxx| 91久久在线播放| 99精品国产福利在线观看免费| 亚洲午夜av| 国产欧美一区二区三区久久| 欧美在线视频在线播放完整版免费观看 | 亚洲国产经典视频| 国产午夜精品福利| 欧美va亚洲va日韩∨a综合色| 蜜桃伊人久久| 中文在线一区| 久久精品国产v日韩v亚洲| 亚洲精品美女在线观看播放| 中文一区二区| 一区在线影院| 99热免费精品| 尤物精品在线| 亚洲一区二区三区免费观看| 一色屋精品视频在线观看网站| 亚洲免费高清| 在线播放豆国产99亚洲| 亚洲精品视频免费在线观看| 国产喷白浆一区二区三区| 亚洲国产欧美另类丝袜| 国产欧美一区二区精品性色| 亚洲激情小视频| 国产亚洲欧美中文| 99在线视频精品| 亚洲激情在线观看视频免费| 亚洲综合色丁香婷婷六月图片| 在线日韩成人| 亚洲欧美日韩网| 99在线精品免费视频九九视| 久久电影一区| 欧美怡红院视频一区二区三区| 欧美激情第10页| 免费国产一区二区| 国产一级揄自揄精品视频| 在线综合亚洲欧美在线视频| 亚洲免费激情| 免费成人高清视频| 久久人人97超碰精品888| 国产精品一卡二卡| 亚洲视频香蕉人妖| 亚洲专区一区二区三区| 欧美激情视频一区二区三区不卡| 卡一卡二国产精品| 国内精品一区二区| 欧美一区二区三区四区在线观看地址 | 欧美肥婆在线| 激情校园亚洲| 久久国产精品黑丝| 久久精品免费观看| 国产麻豆视频精品| 午夜天堂精品久久久久 | 亚洲精品黄色| 女生裸体视频一区二区三区| 六月婷婷一区| 怡红院av一区二区三区| 久久久久成人网| 欧美成人一区二区三区片免费| 国产精品成人免费| 亚洲永久免费视频| 欧美亚一区二区| 一区二区三区高清视频在线观看| 一区二区三区日韩精品视频| 欧美精品亚洲精品| 午夜精品久久久久久久久久久久久| 欧美色精品天天在线观看视频 | 欧美国产精品专区| 欧美一区二区三区在线视频 | 99成人精品| 欧美国产精品一区| 久久久久久久尹人综合网亚洲| 亚洲午夜免费福利视频| 最新日韩在线视频| 在线看视频不卡| 韩国成人福利片在线播放| 国产精品乱码妇女bbbb| 欧美日韩国产三区| 欧美v日韩v国产v| 久久精品视频在线观看| 亚洲欧美日韩精品久久亚洲区 | 日韩香蕉视频| 亚洲第一黄网| 欧美阿v一级看视频| 久久精品国产清高在天天线| 亚洲一区二区三区四区五区午夜| 亚洲国产精品一区二区尤物区| 国产亚洲欧美一级| 国产欧美日韩免费| 国产精品红桃| 国产精品久久久久毛片大屁完整版 | 国产欧美精品在线| 国产精品欧美日韩| 国产精品久久毛片a| 欧美午夜精品理论片a级按摩| 欧美区二区三区| 欧美日韩国产首页| 欧美日韩免费看| 欧美日韩亚洲一区二| 欧美日韩国产一区二区三区| 欧美激情视频在线播放| 欧美日韩精品在线视频| 欧美午夜视频网站| 国产精品亚洲综合色区韩国| 国产日产精品一区二区三区四区的观看方式| 欧美午夜免费影院| 在线观看亚洲a| 91久久久在线| 夜夜夜久久久| 亚洲欧美日韩综合aⅴ视频| 性欧美xxxx大乳国产app| 欧美一区二区免费视频| 久久久久在线| 欧美大片一区二区三区| 欧美色区777第一页| 99精品欧美一区二区三区| 开元免费观看欧美电视剧网站| 久久婷婷影院| 亚洲国产网站|