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

模運算及其應用

goal00001111搜集整理

 

摘要:模運算在數論和程序設計中應用很廣泛,從奇偶數的判別到素數的判別,從模冪運算到最大公約數的求法,從孫子問題到凱撒密碼問題,無不充斥著模運算的身影。本文從模運算的概念,性質,到模運算的基本應用,較為全面的介紹了模運算及其編程方法。

關鍵詞:模運算 程序設計 應用

 

       模運算在數論和程序設計中都有著廣泛的應用,從奇偶數的判別到素數的判別,從模冪運算到最大公約數的求法,從孫子問題到凱撒密碼問題,無不充斥著模運算的身影。雖然很多數論教材上對模運算都有一定的介紹,但多數都是以純理論為主,對于模運算在程序設計中的應用涉及不多。本文以c++語言為載體,對基本的模運算應用進行了分析和程序設計,以理論和實際相結合的方法向大家介紹模運算的基本應用。。

 

基本理論:

基本概念:

給定一個正整數p,任意一個整數n,一定存在等式  n = kp + r
其中k、r是整數,且 0 ≤ r < p,稱呼kn除以p的商,rn除以p的余數。
對于正整數p和整數a,b,定義如下運算: 
取模運算:a % p(或a mod p),表示a除以p的余數。 

p加法:(a + b) % p ,其結果是a+b算術和除以p的余數,也就是說,(a+b) = kp +r,則(a + b) % p = r。 

p減法:(a-b) % p ,其結果是a-b算術差除以p的余數。 

p乘法:(a * b) % p,其結果是 a * b算術乘法除以p的余數。 
說明:

1. 同余式:正整數a,bp取模,它們的余數相同,記做 a ≡ b % p或者a ≡ b (mod p)

2. n % p得到結果的正負由被除數n決定,p無關。例如:7%4 = 3, -7%4 = -3 7%-4 = 3, -7%-4 = -3

基本性質:

1)若p|(a-b),則a≡b (% p)。例如 11 ≡ 4 (% 7), 18 ≡ 4(% 7)

2(a % p)=(b % p)意味a≡b (% p)

3)對稱性:a≡b (% p)等價于b≡a (% p)

4)傳遞性:若a≡b (% p)b≡c (% p) ,則a≡c (% p)

 

運算規則:

模運算與基本四則運算有些相似,但是除法例外。其規則如下:
        (a + b) % p = (a % p + b % p) % p            
1
        (a - b) % p = (a % p - b % p) % p            
2 
        (a * b) % p = (a % p * b % p) % p            
3
       ab % p = ((a % p)b) % p                        
4

結合率: ((a+b) % p + c) % p = (a + (b+c) % p) % p  5

((a*b) % p * c)% p = (a * (b*c) % p) % p   6

交換率: (a + b) % p = (b+a) % p                 7

(a * b) % p = (b * a) % p                 8

分配率: ((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p  9

重要定理:若a≡b (% p),則對于任意的c,都有(a + c) ≡ (b + c) (%p);(10

a≡b (% p),則對于任意的c,都有(a * c) ≡ (b * c) (%p);(11

a≡b (% p)c≡d (% p),則 (a + c) ≡ (b + d) (%p),(a - c) ≡ (b - d) (%p),

(a * c) ≡ (b * d) (%p),(a / c) ≡ (b / d) (%p); 12

a≡b (% p),則對于任意的c,都有ac≡ bc (%p);     13

 

基本應用:

1.判別奇偶數

       奇偶數的判別是模運算最基本的應用,也非常簡單。易知一個整數n2取模,如果余數為0,則表示n為偶數,否則n為奇數。

C++實現功能函數:

       /*

函數名:IsEven

函數功能:判別整數n的奇偶性。能被2整除為偶數,否則為奇數                        

輸入值:int n,整數n

返回值:bool,若整數n是偶數,返回true,否則返回false

*/

bool IsEven(int n)

{

    return (n % 2 == 0);

}

 

2.判別素數

       一個數,如果只有1和它本身兩個因數,這樣的數叫做質數(或素數)。例如 2,3,5,7 是質數,而 46,8,9 則不是,后者稱為合成數或合數。

判斷某個自然數是否是素數最常用的方法就是試除法:用比該自然數的平方根小的正整數去除這個自然數,若該自然數能被整除,則說明其非素數。

C++實現功能函數:

       /*

函數名:IsPrime

函數功能:判別自然數n是否為素數。                                                                         

輸入值:int n,自然數n

返回值:bool,若自然數n是素數,返回true,否則返回false

*/

bool IsPrime(unsigned int n)

{

    unsigned maxFactor = sqrt(n); //n的最大因子

   

    for (unsigned int i=2; i<=maxFactor; i++)

    {

             if (n % i == 0) //n能被i整除,則說明n非素數

             {

               return false;

        }

       }

       return true;

}

 

3. 最大公約數

       求最大公約數最常見的方法是歐幾里德算法(又稱輾轉相除法),其計算原理依賴于定理:gcd(a,b) = gcd(b,a mod b)

證明:a可以表示成a = kb + r,則r = a mod b

假設da,b的一個公約數,則有d|a, d|b,而r = a - kb,因此d|r

因此d(b,a mod b)的公約數

假設d (b,a mod b)的公約數,則d | b , d |r ,但是a = kb +r

因此d也是(a,b)的公約數

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

C++實現功能函數:

/*

函數功能:利用歐幾里德算法,采用遞歸方式,求兩個自然數的最大公約數          

函數名:Gcd

輸入值:unsigned int a,自然數a

        unsigned int b,自然數b

返回值:unsigned int,兩個自然數的最大公約數

*/

unsigned int Gcd(unsigned int a, unsigned int b)

{

    if (b == 0)

        return a;

    return Gcd(b, a % b);

}

/*

函數功能:利用歐幾里德算法,采用迭代方式,求兩個自然數的最大公約數                  函數名:Gcd

輸入值:unsigned int a,自然數a

        unsigned int b,自然數b

返回值:unsigned int,兩個自然數的最大公約數

*/

unsigned int Gcd(unsigned int a, unsigned int b)

{

      unsigned int temp;

    while (b != 0)

    {

        temp = a % b;

        a = b;

        b = temp;

    }

    return a;

}

 

6.模冪運算

       利用模運算的運算規則,我們可以使某些計算得到簡化。例如,我們想知道3333^5555的末位是什么。很明顯不可能直接把3333^5555的結果計算出來,那樣太大了。但我們想要確定的是3333^5555%10),所以問題就簡化了。

       根據運算規則(4ab % p = ((a % p)b) % p  ,我們知道3333^5555%10= 3^5555%10)。由于3^4 = 81,所以3^4%10= 1。

根據運算規則(3 (a * b) % p = (a % p * b % p) % p ,由于5555 = 4 * 1388 + 3,我們得到3^5555%10=3^(4*1388) * 3^3)(%10=((3^(4*1388)%10* 3^3%10))(%10

=1 * 7)(%10= 7。

       計算完畢。

       利用這些規則我們可以有效地計算X^N(% P)。簡單的算法是將result初始化為1,然后重復將result乘以X,每次乘法之后應用%運算符(這樣使得result的值變小,以免溢出),執行N次相乘后,result就是我們要找的答案。

       這樣對于較小的N值來說,實現是合理的,但是當N的值很大時,需要計算很長時間,是不切實際的。下面的結論可以得到一種更好的算法。

       如果N是偶數,那么X^N =X*X^[N/2]

       如果N是奇數,那么X^N = X*X^(N-1) = X *X*X^[N/2]

其中[N]是指小于或等于N的最大整數。

C++實現功能函數:

/*

函數功能:利用模運算規則,采用遞歸方式,計算X^N(% P)    

函數名:PowerMod

輸入值:unsigned int x,底數x

        unsigned int n,指數n

        unsigned int p,模p

返回值:unsigned int,X^N(% P)的結果

*/

unsigned int PowerMod(unsigned int x, unsigned int n, unsigned int p)

{

    if (n == 0)

    {

              return 1;

    }

   

    unsigned int temp = PowerMod((x * x)%p, n/2, p); //遞歸計算(X*X^[N/2]

   

    if ((n & 1) != 0) //判斷n的奇偶性

    {

             temp = (temp * x) % p;

    }

   

    return temp;

}

 

5.《孫子問題(中國剩余定理)

在我國古代算書《孫子算經》中有這樣一個問題:

“今有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二,問物幾何?”意思是,“一個數除以32,除以53,除以72.求適合這個條件的最小數。”

這個問題稱為“孫子問題”.關于孫子問題的一般解法,國際上稱為“中國剩余定理”.

我國古代學者早就研究過這個問題。例如我國明朝數學家程大位在他著的《算法統宗》(1593年)中就用四句很通俗的口訣暗示了此題的解法:

三人同行七十稀,五樹梅花甘一枝,七子團圓正半月,除百零五便得知。

"正半月"暗指15。"除百零五"的原意是,當所得的數比105大時,就105105地往下減,使之小于105;這相當于用105去除,求出余數。

這四句口訣暗示的意思是:當除數分別是3、57時,用70乘以用3除的余數,用21乘以用5除的余數,用15乘以用7除的余數,然后把這三個乘積相加。加得的結果如果比105大,就除以105,所得的余數就是滿足題目要求的最小正整數解。

根據剩余定理,我把此種解法推廣到有n(n為自然數)個除數對應n個余數,求最小被除數的情況。輸入n個除數(除數不能互相整除)和對應的余數,計算機將輸出最小被除數。

C++實現功能函數:

/*

函數名:ResidueTheorem

函數功能:運用剩余定理,解決推廣了的孫子問題。通過給定n個除數(除數不能互相整除)和對應的余數,返回最小被除數                                                                         

輸入值:unsigned int devisor[],存儲了n個除數的數組

        unsigned int remainder[],存儲了n個余數的數組

              int length,數組的長度

返回值:unsigned int, 最小被除數

*/

unsigned int ResidueTheorem(const unsigned int devisor[], const unsigned int remainder[], int length)

{

    unsigned int product = 1; //所有除數之乘積

    for (int i=0; i<length; i++)//計算所有除數之乘積 

       {

             product *= devisor[i];

       }  

      

    //公倍數數組,表示除該元素(除數)之外其他除數的公倍數

    unsigned int *commonMultiple = new unsigned int(length);

       for (int i=0; i<length; i++)//計算除該元素(除數)之外其他除數的公倍數 

       {

             commonMultiple[i] = product / devisor[i];

       } 

      

       unsigned int dividend = 0;  //被除數,就是函數要返回的值

       for (int i=0; i<length; i++)//計算被除數,但此時得到的不是最小被除數

       {

             unsigned int tempMul = commonMultiple[i];

             //按照剩余理論計算合適的公倍數,使得tempMul % devisor[i] == 1

             while (tempMul % devisor[i] != 1)

             {

            tempMul += commonMultiple[i];

           }

          

           dividend += tempMul * remainder[i]; //用本除數得到的余數乘以其他除數的公倍數

       }

   

    delete []commonMultiple;

    return (dividend % product);  //返回最小被除數

}


6.
凱撒密碼

凱撒密碼(caeser)是羅馬擴張時期朱利斯o凱撒(Julius Caesar)創造的,用于加密通過信使傳遞的作戰命令。

它將字母表中的字母移動一定位置而實現加密。注意26個字母循環使用,z的后面可以堪稱是a

例如,當密匙為k = 3,即向后移動3位時,若明文為”How are you!”,則密文為”Krz duh btx!”。

凱撒密碼的加密算法極其簡單。其加密過程如下:

在這里,我們做此約定:明文記為m,密文記為c,加密變換記為E(key1,m)(其中key1為密鑰),

解密變換記為D(key2,m)key2為解密密鑰)(在這里key1=key2,不妨記為key)。

凱撒密碼的加密過程可記為如下一個變換:cm+key (mod n (其中n為基本字符個數)

同樣,解密過程可表示為:mc+key (mod n (其中n為基本字符個數)
C++
實現功能函數:

/*

函數功能:使用凱撒密碼原理,對明文進行加密,返回密文                                          函數名:Encrypt

輸入值:const char proclaimedInWriting[],存儲了明文的字符串

        char cryptograph[],用來存儲密文的字符串

              int keyey,加密密匙,正數表示后移,負數表示前移

返回值:無返回值,但是要將新的密文字符串返回

*/

void Encrypt(const char proclaimedInWriting[], char cryptograph[], int key)

{

    const int NUM = 26; //字母個數

    int len = strlen(proclaimedInWriting);

   

    for (int i=0; i<len; i++)

    {

             if (proclaimedInWriting[i] >= 'a' && proclaimedInWriting[i] <= 'z')

             {//明碼是大寫字母,則密碼也為大寫字母

            cryptograph[i] = (proclaimedInWriting[i] - 'a' + key) % NUM + 'a';

        }

             else if (proclaimedInWriting[i] >= 'A' && proclaimedInWriting[i] <= 'Z')

             {//明碼是小寫字母,則密碼也為小寫字母

            cryptograph[i] = (proclaimedInWriting[i] - 'A' + key) % NUM + 'A';

        }

        else

        {//明碼不是字母,則密碼與明碼相同

            cryptograph[i] = proclaimedInWriting[i];

        }

       }

       cryptograph[len] = '\0';

}

 

/*

函數功能:使用凱撒密碼原理,對密文進行解密,返回明文                                          函數名:Decode

輸入值:char proclaimedInWriting[],用來存儲明文的字符串

        const char cryptograph[],存儲了密文的字符串

              int keyey,解密密匙,正數表示前移,負數表示后移(與加密相反)

返回值:無返回值,但是要將新的明文字符串返回

*/

void Decode(const char cryptograph[], char proclaimedInWriting[], int key)

{

    const int NUM = 26; //字母個數

    int len = strlen(cryptograph);

   

    for (int i=0; i<len; i++)

    {

             if (cryptograph[i] >= 'a' && cryptograph[i] <= 'z')

             {//密碼是大寫字母,則明碼也為大寫字母,為防止出現負數,轉換時要加個NUM

          proclaimedInWriting[i] = (cryptograph[i] - 'a' - key + NUM) % NUM + 'a';

        }

             else if (cryptograph[i] >= 'A' && cryptograph[i] <= 'Z')

             {//密碼是小寫字母,則明碼也為小寫字母

            proclaimedInWriting[i] = (cryptograph[i] - 'A' - key + NUM) % NUM + 'A';

        }

        else

        {//密碼不是字母,則明碼與明密相同

            proclaimedInWriting[i] = cryptograph[i];

        }

       }

       proclaimedInWriting[len] = '\0';

}

 

       模運算及其簡單應用就先講到這了,其實模運算在數學及計算機領域的應用非常廣泛,我這這里搜集整理了一些最最基本的情形,希望能夠起到一個拋磚引玉的作用,讓更多的人關注模運算,并及其應用到更廣闊的領域中。      

 

參考文獻:

1.       《模運算》百度貼吧http://tieba.baidu.com/f?kz=30549931;

2.       《模運算性質》 中國百科網

http://www.chinabaike.com/article/316/shuxue/2007/20071005554776.html

3.       《數據結構與問題求解》 Mark Allen Weiss清華大學出版社

4.       《孫子問題(中國剩余定理)

http://hi.baidu.com/bjxiaoyao/blog/item/55ce951001d57d00213f2e30.html

5.       《破解凱撒kaiser密碼》

http://bbs.sei.ynu.edu.cn/viewthread.php?tid=5734

 

 

      

 

      

Posted on 2008-10-25 11:51 夢想飛揚 閱讀(442) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   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>
            另类欧美日韩国产在线| 午夜欧美视频| 欧美精品一区二区三区蜜桃| 久色婷婷小香蕉久久| 久久久精品国产免大香伊| 欧美一区二区在线看| 欧美专区福利在线| 久久久一区二区三区| 美女视频黄a大片欧美| 欧美精品尤物在线| 国产精品免费在线| 欧美日韩一区二区三区在线| 亚洲人成人一区二区在线观看| 欧美大片一区二区三区| 亚洲高清视频的网址| 日韩一区二区精品在线观看| 亚洲欧美精品一区| 久热成人在线视频| 国产精品sss| 国产一区香蕉久久| 99精品99| 久久婷婷人人澡人人喊人人爽| 亚洲国产精品123| 亚洲综合欧美日韩| 麻豆久久精品| 国产精品免费视频观看| 亚洲人精品午夜在线观看| 小嫩嫩精品导航| 亚洲国产精品小视频| 欧美亚洲三区| 亚洲综合999| 亚洲女人天堂av| 欧美主播一区二区三区| 欧美电影免费观看网站| 亚洲制服欧美中文字幕中文字幕| 久久婷婷蜜乳一本欲蜜臀| 欧美系列精品| 最新成人在线| 久久亚洲欧美| 午夜精品美女自拍福到在线 | 亚洲黄色成人| 久久久欧美精品sm网站| 亚洲手机在线| 欧美日韩一二三区| 亚洲美女av电影| 欧美大片专区| 久久婷婷麻豆| 一区二区三区在线观看视频| 欧美一级在线播放| 亚洲私人影院| 国产精品乱码一区二区三区| 亚洲一区二区三区777| 亚洲黄一区二区三区| 狼人天天伊人久久| 亚洲高清自拍| 欧美黄色免费网站| 久久综合九色综合欧美就去吻 | 黄色亚洲大片免费在线观看| 欧美一二三区在线观看| 亚洲视频二区| 国产精品一区免费视频| 欧美一区二区三区另类| 亚洲欧美国产三级| 国产午夜精品理论片a级探花| 午夜精品久久99蜜桃的功能介绍| 一本色道久久加勒比精品| 欧美色视频在线| 亚洲欧美中文日韩v在线观看| 一区二区欧美日韩| 国产精品久久夜| 久久激情网站| 久久亚洲一区二区三区四区| 在线免费观看欧美| 欧美成人激情视频| 欧美激情精品久久久久久变态 | 激情伊人五月天久久综合| 另类酷文…触手系列精品集v1小说| 欧美一区二区三区另类 | 欧美一区二区三区喷汁尤物| 午夜欧美视频| 亚洲电影av在线| 日韩一区二区电影网| 国产精品亚洲片夜色在线| 久久久亚洲一区| 99国产精品99久久久久久粉嫩| 国产麻豆视频精品| 久久蜜桃香蕉精品一区二区三区| 久久久成人网| 在线亚洲欧美视频| 西西裸体人体做爰大胆久久久| 国产日产精品一区二区三区四区的观看方式| 久久精品99久久香蕉国产色戒| 久久9热精品视频| 亚洲精品欧美| 欧美一区二区成人6969| 亚洲啪啪91| 欧美亚洲三级| 99这里只有久久精品视频| 先锋影音国产一区| 99re热精品| 久久久久久久波多野高潮日日| 一本一本久久| 久久午夜电影网| 欧美一区2区三区4区公司二百| 欧美成人xxx| 久久久人成影片一区二区三区观看 | 性欧美xxxx大乳国产app| 亚洲二区视频| 亚洲欧美国产三级| av不卡在线观看| 久久亚洲精品欧美| 香蕉尹人综合在线观看| 欧美日韩国产综合视频在线| 蜜臀av国产精品久久久久| 国产精品久久久久久久久免费| 欧美大尺度在线| 国产一二精品视频| 亚洲欧美成人在线| 亚洲一卡久久| 欧美日韩精品免费观看视频完整| 免费在线成人| 黄色亚洲大片免费在线观看| 午夜欧美电影在线观看| 亚洲综合色噜噜狠狠| 欧美日韩成人一区二区三区| 欧美韩国日本综合| 亚洲第一黄网| 美女精品在线观看| 欧美大片在线观看一区| 禁断一区二区三区在线| 欧美一区二区视频免费观看| 欧美一级久久久| 国产精品日韩欧美大师| 一区二区三区免费看| 亚洲先锋成人| 国产精品久久综合| 亚洲视频axxx| 欧美综合国产精品久久丁香| 国产精品中文字幕在线观看| 亚洲永久免费精品| 久久成人精品无人区| 国产日韩欧美一二三区| 欧美一区二区三区在线播放| 久久久久久9| 精品不卡一区| 老司机精品视频网站| 欧美国产日产韩国视频| 久久久精品国产99久久精品芒果| 亚洲美女视频在线观看| 欧美剧在线免费观看网站| 亚洲美女av网站| 午夜精品免费在线| 国产日韩在线视频| 久久久噜噜噜久久狠狠50岁| 欧美成人国产一区二区| 亚洲人成在线播放| 欧美性一区二区| 欧美一二三视频| 亚洲福利视频一区二区| 亚洲无线视频| 韩国一区二区三区美女美女秀| 麻豆国产精品va在线观看不卡| 亚洲日韩欧美视频| 午夜亚洲精品| 亚洲第一狼人社区| 欧美日韩亚洲综合在线| 欧美一级专区| 亚洲人体影院| 久久久91精品国产| 亚洲精品中文字幕在线| 国产精品视频区| 老司机成人网| 亚洲一区二区在线免费观看视频 | 欧美精品v日韩精品v国产精品| 日韩午夜av电影| 麻豆freexxxx性91精品| 亚洲少妇一区| 亚洲电影av在线| 国产精品麻豆va在线播放| 久久综合电影一区| 亚洲一区二区三区午夜| 亚洲国产日韩精品| 久久久国产一区二区| a4yy欧美一区二区三区| 狠狠色丁香婷婷综合影院| 欧美体内谢she精2性欧美| 久久夜色精品国产| 亚洲欧美日韩在线播放| 亚洲久久一区| 欧美黑人在线观看| 久久久青草婷婷精品综合日韩 | 亚洲图片欧美日产| 亚洲国产欧美一区| 久久午夜激情| 欧美影视一区| 亚洲综合色激情五月| 一区二区三区免费观看| 亚洲激情一区二区三区| 伊人久久大香线蕉av超碰演员| 国产精品爱啪在线线免费观看|