• <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>
            posts - 297,  comments - 15,  trackbacks - 0
            轉(zhuǎn)自:::::http://blog.chinaunix.net/u2/76292/showart_1418158.html
            1. 歐幾里德算法和擴(kuò)展歐幾里德算法

            歐幾里德算法
            歐幾里德算法又稱輾轉(zhuǎn)相除法,用于計(jì)算兩個(gè)整數(shù)a,b的最大公約數(shù)。其計(jì)算原理依賴于下面的定理:

            定理:gcd(a,b) = gcd(b,a mod b)

            證明:a可以表示成a = kb + r,則r = a mod b
            假設(shè)d是a,b的一個(gè)公約數(shù),則有
            d|a, d|b,而r = a - kb,因此d|r
            因此d是(b,a mod b)的公約數(shù)

            假設(shè)d 是(b,a mod b)的公約數(shù),則
            d | b , d |r ,但是a = kb +r
            因此d也是(a,b)的公約數(shù)

            因此(a,b)和(b,a mod b)的公約數(shù)是一樣的,其最大公約數(shù)也必然相等,得證

            歐幾里德算法就是根據(jù)這個(gè)原理來(lái)做的,其算法用C++語(yǔ)言描述為:

            int Gcd(int a, int b)
            {
                
            if(b == 0)
                    
            return a;
                
            return Gcd(b, a % b);
            }

            當(dāng)然你也可以寫(xiě)成迭代形式:
            int Gcd(int a, int b)
            {
                
            while(b != 0)
                
            {
                    
            int r = b;
                    b 
            = a % b;
                    a 
            = r;
                }

                
            return a;
            }

            本質(zhì)上都是用的上面那個(gè)原理。

            補(bǔ)充: 擴(kuò)展歐幾里德算法是用來(lái)在已知a, b求解一組p,q使得p * a+q  * b = Gcd(a, b)  (解一定存在,根據(jù)數(shù)論中的相關(guān)定理)。擴(kuò)展歐幾里德常用在求解模線性方程及方程組中。下面是一個(gè)使用C++的實(shí)現(xiàn):
            int exGcd(int a, int b, int &x, int &y)
            {
                
            if(b == 0)
                
            {
                    x 
            = 1;
                    y 
            = 0;
                    
            return a;
                }

                
            int r = exGcd(b, a % b, x, y);
                
            int t = x;
                x 
            = y;
                y 
            = t - a / b * y;

                
            return r;
            }

            把這個(gè)實(shí)現(xiàn)和Gcd的遞歸實(shí)現(xiàn)相比,發(fā)現(xiàn)多了下面的x,y賦值過(guò)程,這就是擴(kuò)展歐幾里德算法的精髓。
            可以這樣思考:
            對(duì)于a' = b, b' = a % b 而言,我們求得 x, y使得 a'x + b'y = Gcd(a', b')
            由于b' = a % b = a - a / b * b (注:這里的/是程序設(shè)計(jì)語(yǔ)言中的除法)
            那么可以得到:
            a'x + b'y = Gcd(a', b')  ===>
            bx + (a - a / b * b)y = Gcd(a', b') = Gcd(a, b)  ===>
            ay +b(x - a / b*y) = Gcd(a, b)
            因此對(duì)于a和b而言,他們的相對(duì)應(yīng)的p,q分別是 y和(x-a/b*y)

            2. Stein算法
            歐幾里德算法是計(jì)算兩個(gè)數(shù)最大公約數(shù)的傳統(tǒng)算法,他無(wú)論從理論還是從效率上都是很好的。但是他有一個(gè)致命的缺陷,這個(gè)缺陷只有在大素?cái)?shù)時(shí)才會(huì)顯現(xiàn)出來(lái)。

            考慮現(xiàn)在的硬件平臺(tái),一般整數(shù)最多也就是64位,對(duì)于這樣的整數(shù),計(jì)算兩個(gè)數(shù)之間的模是很簡(jiǎn)單的。對(duì)于字長(zhǎng)為32位的平臺(tái),計(jì)算兩個(gè)不超過(guò)32位的整數(shù)的模,只需要一個(gè)指令周期,而計(jì)算64位以下的整數(shù)模,也不過(guò)幾個(gè)周期而已。但是對(duì)于更大的素?cái)?shù),這樣的計(jì)算過(guò)程就不得不由用戶來(lái)設(shè)計(jì),為了計(jì)算兩個(gè)超過(guò) 64位的整數(shù)的模,用戶也許不得不采用類似于多位數(shù)除法手算過(guò)程中的試商法,這個(gè)過(guò)程不但復(fù)雜,而且消耗了很多CPU時(shí)間。對(duì)于現(xiàn)代密碼算法,要求計(jì)算 128位以上的素?cái)?shù)的情況比比皆是,設(shè)計(jì)這樣的程序迫切希望能夠拋棄除法和取模。 (注:說(shuō)到拋棄除法和取模,其實(shí)輾轉(zhuǎn)相除法可以寫(xiě)成減法的形式)

            Stein算法由J. Stein 1961年提出,這個(gè)方法也是計(jì)算兩個(gè)數(shù)的最大公約數(shù)。和歐幾里德算法 算法不同的是,Stein算法只有整數(shù)的移位和加減法,這對(duì)于程序設(shè)計(jì)者是一個(gè)福音。

            為了說(shuō)明Stein算法的正確性,首先必須注意到以下結(jié)論:

            gcd(a,a) = a,也就是一個(gè)數(shù)和他自身的公約數(shù)是其自身
            gcd(ka,kb) = k gcd(a,b),也就是最大公約數(shù)運(yùn)算和倍乘運(yùn)算可以交換,特殊的,當(dāng)k=2時(shí),說(shuō)明兩個(gè)偶數(shù)的最大公約數(shù)必然能被2整除。

            有了上述規(guī)律就可以給出Stein算法如下:

            如果A=0,B是最大公約數(shù),算法結(jié)束
            如果B=0,A是最大公約數(shù),算法結(jié)束
            設(shè)置A1 = A、B1=B和C1 = 1
            如果An和Bn都是偶數(shù),則An+1 =An /2,Bn+1 =Bn /2,Cn+1 =Cn *2(注意,乘2只要把整數(shù)左移一位即可,除2只要把整數(shù)右移一位即可)
            如果An是偶數(shù),Bn不是偶數(shù),則An+1 =An /2,Bn+1 =Bn ,Cn+1 =Cn (很顯然啦,2不是奇數(shù)的約數(shù))
            如果Bn是偶數(shù),An不是偶數(shù),則Bn+1 =Bn /2,An+1 =An ,Cn+1 =Cn (很顯然啦,2不是奇數(shù)的約數(shù))
            如果An和Bn都不是偶數(shù),則An+1 =|An -Bn|,Bn+1 =min(An,Bn),Cn+1 =Cn
            n++,轉(zhuǎn)4
            這個(gè)算法的原理很顯然,所以就不再證明了。現(xiàn)在考察一下該算法和歐幾里德方法效率上的差別。

            給出一個(gè)C++的實(shí)現(xiàn):

            int Gcd(int a, int b)
            {
                
            if(a == 0return b;
                
            if(b == 0return a;
                
            if(a % 2 == 0 && b % 2 == 0return 2 * gcd(a >> 1, b >> 1);
                
            else if(a % 2 == 0)  return gcd(a >> 1, b);
                
            else if(b % 2 == 0return gcd(a, b >> 1);
                
            else return gcd(abs(a - b), Min(a, b));
            }

            考慮歐幾里德算法,最惡劣的情況是,每次迭代a = 2b -1,這樣,迭代后,r= b-1。如果a小于2N,這樣大約需要 4N次迭代。而考慮Stein算法,每次迭代后,顯然AN+1BN+1≤ ANBN/2,最大迭代次數(shù)也不超過(guò)4N次。也就是說(shuō),迭代次數(shù)幾乎是相等的。但是,需要注意的是,對(duì)于大素?cái)?shù),試商法將使每次迭代都更復(fù)雜,因此對(duì)于大素?cái)?shù)Stein將更有優(yōu)勢(shì)

            練習(xí):
            OJ上面的赤裸裸的Gcd算法的題不多,大多都是套了一個(gè)外殼。
            找了兩道,可以試試看
            HDOJ 2028 Lowest Common Multiple Plus   這個(gè)是求n個(gè)數(shù)的最小公倍數(shù)(有了最大公約數(shù),最小公倍數(shù)應(yīng)該很容易了)
            ZJU 2678 Bishops on a Toral Board  這個(gè)題目要發(fā)現(xiàn)規(guī)律,不錯(cuò)的題目很老的東東了,其實(shí)也沒(méi)啥好整理的,網(wǎng)上很多資料了,就當(dāng)備用把:-)
            posted on 2009-05-31 19:09 chatler 閱讀(5477) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Algorithm
            <2009年11月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺(jué)這個(gè)博客還是不錯(cuò),雖然做的東西和我不大相關(guān),覺(jué)得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            无码八A片人妻少妇久久| 99蜜桃臀久久久欧美精品网站| 久久久久久久综合日本| 伊人久久综在合线亚洲2019| 久久丫精品国产亚洲av不卡 | 伊色综合久久之综合久久| 免费精品99久久国产综合精品| 国产V综合V亚洲欧美久久| 青青草原精品99久久精品66| 久久婷婷国产综合精品| 久久一日本道色综合久久| 99re久久精品国产首页2020| 国产精品久久久久久久久鸭| 久久精品成人国产午夜| 国产69精品久久久久9999| 久久精品国产WWW456C0M| 色综合久久88色综合天天 | 国产精品久久久久免费a∨| 亚洲愉拍99热成人精品热久久 | 国产成人久久精品一区二区三区| 亚洲av伊人久久综合密臀性色| 无码超乳爆乳中文字幕久久| 久久电影网2021| 欧洲国产伦久久久久久久| 久久伊人五月丁香狠狠色| 久久精品国产亚洲av麻豆色欲| 国产精品久久99| 色天使久久综合网天天| 日本欧美久久久久免费播放网| 亚洲国产精品久久久久婷婷软件| 精品久久久久久无码人妻蜜桃| 日韩精品久久久久久久电影| 久久精品国产网红主播| 欧美久久久久久午夜精品| 无码久久精品国产亚洲Av影片 | 波多野结衣久久精品| 久久久亚洲欧洲日产国码二区| 国产精品成人99久久久久| 亚洲人成伊人成综合网久久久| 国产L精品国产亚洲区久久 | 欧美精品福利视频一区二区三区久久久精品 |