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

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

using namespace std;

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

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

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

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

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

template <class T> //交換兩個(gè)長(zhǎng)度均為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> //一個(gè)類似于歐幾里得算法的旋轉(zhuǎn)算法
void GcdRotate(T a[], int n, int r);

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

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

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

int main()
{
    const int N = 601; //測(cè)試次數(shù)
    const int MAX = 500000; //向量長(zhǎng)度
    int a[MAX] = {0};
    int rotateDistance = 100000;
    time_t startTime, endTime;
    
   ////////最簡(jiǎn)單的直接移動(dòng)向量旋轉(zhuǎn)算法///////////////////////////////  
    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;
    ///////////////////////////////////////////////////////////////////////////////////////////
    //////////簡(jiǎn)明的的逆置數(shù)組旋轉(zhuǎn)算法//////////////////////////////////////////////////  
    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;
    ///////////////////////////////////////////////////////////////////////////////////////////
    ////////////傳說(shuō)中的雜耍旋轉(zhuǎn)算法 //////////////////////////////////////  
    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;
    ///////////////////////////////////////////////////////////////////////////////////////////
    /////////////一個(gè)類似于歐幾里得算法的旋轉(zhuǎn)算法///////////////////////////////////  
    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;
}

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

/*
函數(shù)名稱:ReverseRotate
函數(shù)功能:簡(jiǎn)明的的逆置數(shù)組旋轉(zhuǎn)算法:構(gòu)造一個(gè)逆置數(shù)組的原子操作子函數(shù),然后設(shè)置不同的數(shù)組左右界,
          分三次調(diào)用子函數(shù)就行了。因?yàn)槊總€(gè)元素都需要移動(dòng)兩次,所以效率不是很高。
輸入?yún)?shù):T a[]:需要被旋轉(zhuǎn)的向量
          int n:向量的長(zhǎng)度
          int r:向量左半段長(zhǎng)度
輸出參數(shù):T a[]:旋轉(zhuǎn)后的向量
返回值:無(wú)
*/
template <class T>
void ReverseRotate(T a[], int n, int r)
{   
    Reverse(a, 0, r-1); //逆置左半段數(shù)組
    Reverse(a, r, n-1); //逆置右半段數(shù)組
    Reverse(a, 0, n-1); //逆置整段數(shù)組
}
////////////////////////////////////////////////////////////////////////////////////////////////
//////////////方法三:傳說(shuō)中的雜耍旋轉(zhuǎn)算法////////////////////////////////////////////////

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

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

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

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

/*
函數(shù)名稱:CheckRotate
函數(shù)功能:判斷向量旋轉(zhuǎn)是否成功
輸入?yún)?shù):T a[]:需要被旋轉(zhuǎn)的向量
          int n:向量的長(zhǎng)度
          int r:向量左半段長(zhǎng)度
輸出參數(shù):無(wú)
返回值:旋轉(zhuǎn)成功返回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 夢(mèng)想飛揚(yáng) 閱讀(764) 評(píng)論(0)  編輯 收藏 引用

只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美阿v一级看视频| 亚洲国产一区二区三区青草影视| 久久精品国产999大香线蕉| 国产精品久久久久久影视| 亚洲一级二级在线| 亚洲高清久久久| 亚洲人成欧美中文字幕| 亚洲五月婷婷| 国产一区亚洲| 国产精品免费看片| 伊人蜜桃色噜噜激情综合| 欧美二区在线播放| 欧美激情成人在线| 欧美影院一区| 亚洲午夜一区二区| 欧美一区二区啪啪| 久久国产福利| 久久精品99无色码中文字幕| 美女主播视频一区| 99www免费人成精品| 在线看视频不卡| 日韩午夜免费视频| 欧美在线一二三四区| 在线日韩一区二区| 亚洲成人在线观看视频| 国产精品99久久久久久有的能看| 99re6热在线精品视频播放速度| 一色屋精品视频在线观看网站| 亚洲大片一区二区三区| 久久亚洲电影| 午夜影视日本亚洲欧洲精品| 亚洲国内精品在线| 亚洲一区网站| 亚洲一区二区三区欧美| 亚洲视频中文| 久久久久久久999| 久久精品国产成人| 国产精品永久免费视频| 在线播放国产一区中文字幕剧情欧美| 亚洲精品社区| 亚洲啪啪91| 久久精品免视看| 亚洲精品久久| 六十路精品视频| 亚洲精品日韩久久| 欧美成人一区二区| 国产揄拍国内精品对白| 日韩一级黄色av| 亚洲精品一区二区三区四区高清 | 美女精品网站| 国产一区免费视频| 麻豆精品一区二区综合av | 欧美中文字幕视频在线观看| 久久免费视频在线| 国产一区二区三区四区老人| 久久久亚洲影院你懂的| 免费一区视频| 欧美一区二区三区四区在线观看| 久久综合亚州| 先锋亚洲精品| 欧美—级高清免费播放| 久久久水蜜桃av免费网站| 国产精品久久久久久久久婷婷| 国产精品专区第二| 日韩一本二本av| 欧美+日本+国产+在线a∨观看| 亚洲女同同性videoxma| 国语自产精品视频在线看抢先版结局| **性色生活片久久毛片| 亚洲高清色综合| 欧美在线视频a| 国产精品国内视频| 亚洲欧美综合| 一区二区三区精品视频| 国产精品日韩精品欧美在线 | 免费观看成人网| 亚洲视频在线一区| 韩国一区二区三区美女美女秀| 亚洲精品你懂的| 欧美高清在线| 欧美成人午夜剧场免费观看| 亚洲欧美在线免费观看| 欧美一级淫片播放口| 亚洲风情在线资源站| 亚洲狼人综合| 欧美日韩午夜视频在线观看| 亚洲综合欧美日韩| 老鸭窝亚洲一区二区三区| 亚洲一区二区三区欧美| 国产一区二区三区在线免费观看 | 亚洲男女毛片无遮挡| 一本色道久久综合亚洲精品不| 亚洲视频在线观看视频| 国产目拍亚洲精品99久久精品 | 老色鬼久久亚洲一区二区| 久久免费视频一区| 在线亚洲免费| 亚洲欧美一区二区精品久久久| 免费亚洲电影在线观看| 久久精品一区二区国产| 国产精品久久一卡二卡| 亚洲美女精品成人在线视频| 久久嫩草精品久久久精品一| 久久夜精品va视频免费观看| 亚洲毛片播放| 欧美日韩喷水| 亚洲黄页一区| 最新亚洲激情| 午夜日韩在线| 欧美黑人一区二区三区| 国产欧美高清| 亚洲视频大全| 99视频一区二区| 国产一区二区三区网站| 亚洲欧美日韩在线不卡| 亚洲专区在线| 久久久久久夜精品精品免费| 欧美在线91| 亚洲国产婷婷香蕉久久久久久| 欧美视频在线观看视频极品 | 午夜在线视频观看日韩17c| 亚洲三级电影在线观看| 欧美在线播放| 久久九九精品| 欧美日韩国产影片| 国产最新精品精品你懂的| 激情综合色丁香一区二区| 欧美在线你懂的| 久久久亚洲高清| 国产一区二区三区四区在线观看| 久久国产色av| 欧美刺激性大交免费视频| 亚洲精品在线观| 99re66热这里只有精品3直播| 麻豆成人在线观看| 久久精品国产第一区二区三区| 亚洲欧洲av一区二区| 99天天综合性| 亚洲精品网址在线观看| 午夜精品99久久免费| 久热这里只精品99re8久| 亚洲人成人77777线观看| 欧美丰满高潮xxxx喷水动漫| 欧美日韩性视频在线| 欧美精品v国产精品v日韩精品| 国产伦精品免费视频| 亚洲精品自在在线观看| 影院欧美亚洲| 欧美成人一区二区在线| 乱码第一页成人| 一区二区欧美日韩视频| 久久人人爽人人爽爽久久| 亚洲经典三级| 久久久久久久久综合| 一本在线高清不卡dvd| 一本色道婷婷久久欧美| 91久久在线| 免费影视亚洲| 亚洲欧美日韩国产一区二区| 噜噜噜噜噜久久久久久91| 亚洲综合色在线| 久久精品国产精品亚洲综合 | 欧美91视频| 午夜精品剧场| 久久精品99久久香蕉国产色戒| 欧美激情第1页| 在线播放视频一区| 欧美激情精品久久久久| 亚洲无限av看| 亚洲精品在线三区| 巨乳诱惑日韩免费av| 欧美v国产在线一区二区三区| 国产精品久久久久久久一区探花 | 欧美成人一区二区三区在线观看| 久久久久久网| 国语自产精品视频在线看8查询8 | 小黄鸭精品aⅴ导航网站入口| 日韩亚洲成人av在线| 欧美一区1区三区3区公司| 久久人人97超碰精品888| 狠狠久久亚洲欧美| 玖玖在线精品| 欧美精品三级日韩久久| 午夜欧美大片免费观看| 欧美精品色一区二区三区| 亚洲国内精品| 亚洲最黄网站| 你懂的视频一区二区| 欧美偷拍另类| 欧美三级乱码| 欧美不卡一区| 久久精品国产免费| 99在线精品观看| 欧美激情按摩在线| 久久久久亚洲综合| 欧美一区二区三区在线| 久久久久国产一区二区| 欧美在线一区二区三区| 欧美手机在线| 国产精品国产三级国产|