1樓:匿名使用者
基本理論
基本概念:
給定一個正整數p,任意一個整數n,一定存在等式 n = kp + r ;
其中k、r是整數,且 0 ≤ r < p,稱呼k為n除以p的商,r為n除以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,b對p取模,它們的餘數相同,記做 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.判別奇偶數
奇偶數的判別是模運算最基本的應用,也非常簡單。易知一個整數n對2取模,如果餘數為0,則表示n為偶數,否則n為奇數。
c++實現功能函式:
/*函式名:iseven
函式功能:判別整數n的奇偶性。能被2整除為偶數,否則為奇數
輸入值:int n,整數n
返回值:bool,若整數n是偶數,返回true,否則返回false
*/bool iseven(int n)
2.判別素數
一個數,如果只有1和它本身兩個因數,這樣的數叫做質數(或素數)。例如 2,3,5,7 是質數,而 4,6,8,9 則不是,後者稱為合成數或合數。
判斷某個自然數是否是素數最常用的方法就是試除法:用比該自然數的平方根小的正整數去除這個自然數,若該自然數能被整除,則說明其非素數。
c++實現功能函式:
/*函式名:isprime
函式功能:判別自然數n是否為素數。
輸入值:int n,自然數n
返回值:bool,若自然數n是素數,返回true,否則返回false
*/bool isprime(unsigned int n)
}return true;
}3. 最大公約數
求最大公約數最常見的方法是歐幾里德演算法(又稱輾轉相除法),其計算原理依賴於定理:***(a,b) = ***(b,a mod b)
證明:a可以表示成a = kb + r,則r = a mod b
假設d是a,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++實現功能函式:
/*函式功能:利用歐幾里德演算法,採用遞迴方式,求兩個自然數的最大公約數
函式名:***
輸入值:unsigned int a,自然數a
unsigned int b,自然數b
返回值:unsigned int,兩個自然數的最大公約數
*/unsigned int ***(unsigned int a, unsigned int b)
/*函式功能:利用歐幾里德演算法,採用迭代方式,求兩個自然數的最大公約數 函式名:***
輸入值:unsigned int a,自然數a
unsigned int b,自然數b
返回值:unsigned int,兩個自然數的最大公約數
*/unsigned int ***(unsigned int a, unsigned int b)
return a;
}4.模冪運算
利用模運算的運算規則,我們可以使某些計算得到簡化。例如,我們想知道3333^5555的末位是什麼。很明顯不可能直接把3333^5555的結果計算出來,那樣太大了。
但我們想要確定的是3333^5555(%10),所以問題就簡化了。
根據運算規則(4)ab % 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)
unsigned int temp = powermod((x * x)%p, n/2, p); //遞迴計算(x*x)^[n/2]
if ((n & 1) != 0) //判斷n的奇偶性
return temp;
}5.《孫子問題(中國剩餘定理)》
在我國古代算書《孫子算經》中有這樣一個問題:
「今有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二,問物幾何?」意思是,「一個數除以3餘2,除以5餘3,除以7餘2.求適合這個條件的最小數。」
這個問題稱為「孫子問題」.關於孫子問題的一般解法,國際上稱為「中國剩餘定理」.
我國古代學者早就研究過這個問題。例如我國明朝數學家程大位在他著的《演算法統宗》(2023年)中就用四句很通俗的口訣暗示了此題的解法:
三人同行七十稀,五樹梅花甘一枝,七子團圓正半月,除百零五便得知。
"正半月"暗指15。"除百零五"的原意是,當所得的數比105大時,就105、105地往下減,使之小於105;這相當於用105去除,求出餘數。
這四句口訣暗示的意思是:當除數分別是3、5、7時,用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)
else if (proclaimedinwriting[i] >= 'a' && proclaimedinwriting[i] <= 'z')
else
}cryptograph[len] = '\0';}/*
函式功能:使用凱撒密碼原理,對密文進行解密,返回明文 函式名:decode
輸入值:char proclaimedinwriting,用來儲存明文的字串
const char cryptograph,儲存了密文的字串
int keyey,解密密匙,正數表示前移,負數表示後移(與加密相反)
返回值:無返回值,但是要將新的明文字串返回
*/void decode(const char cryptograph, char proclaimedinwriting, int key)
else if (cryptograph[i] >= 'a' && cryptograph[i] <= 'z')
else
}proclaimedinwriting[len] = '\0';}
沙漏原理是怎麼回事啊,沙漏原理是怎麼回事啊?
沙漏原理就是說沙漏定理即八字定理,有兩個相似三角形組成,abc和 xyz,面積分別為s1和s2,s1 s2 ab bc xy yz。用 s 1 2 ab sinc,容易推導 沙漏也叫做沙鍾,是一種測量時間的裝置。西方沙漏由兩個玻璃球和一個狹窄的連線管道組成的。通過充滿了沙子的玻璃球從上面穿過狹窄的管...
關於c語言取餘與取模運算的問題求詳細解釋
它不是說得復 很詳細了麼,向負無 制窮方向 舍入 floor 函式 又稱為地板函式,與之相對還有天花板函式 往小方向取整,即向負無窮方向取整 8 3 2.67的地板為2 即模為2 8 3 2.67的地板為 3 即模為 3 c語言中的 取餘 是什麼意思?要詳細 其實求餘襲運算可以看成 a b a in...
在C語言中,關於取餘的,若 9 2的運算結果是啥 幫忙解答一下,謝謝
咱們用的c語言,一般都是c89的 我翻看了下,那本k r的那本書,它主要就是介紹c89的,上面是這麼寫的 a b a b,前者取商,後者求餘 如果b為0,結果未定義,否則 a b b a b 總是會等於 a 如果a,b都是非負的,那麼a b結果非負,且小於b,也就是 9 2 結果一定會是 1 除此之...