c语言同余法

你可以直接把所有的题都算出来,每次都把算出来的结果记录下来。如果已经生成了计算结果,证明你在一个循环中,无法生成0到m-1的所有数。如果你找到了所有的数字,你就可以生成所有的数字。

rand()%m在C语言中是什么意思? Rand()%m这个函数随机生成一个从0到m-1的随机数;例如,rand()是从0到9随机生成的随机数。

扩展信息

C语言的rand函数用于生成伪随机数。

c语言中rand函数的使用

1.编写头文件

2.变量的定义

3、srand((无符号)时间(空));/*选择种子文件*/

4、for(I = 0;i 20I) /*循环控制20个随机数的产生*/

{ k=rand()0;/*存储随机数*/printf ("k =% d \ n ",k);/*输出随机数*/}}

(1)这是一种产生随机函数的方法。

(2)如果只需要一个,循环控制可以省略。

使用rand函数生成随机数:

函数rand()是一个实随机数生成器,srand()为rand()设置随机数种子。如果你在第一次调用rand()之前没有调用srand(),系统会自动为你调用srand()。使用与种子相同的数字调用srand()将导致生成相同的随机数序列。

Srand((无符号)time(NULL))使用系统定时器/计数器的值作为随机种子。每个种子对应一组根据算法预先生成的随机数,所以在同一平台环境下,不同时间生成的随机数会有所不同。相应地,如果将srand(unsigned)time(NULL)改为srand(TP)(TP为任意常数),那么无论运行多少次,得到的“随机数”都将是一组固定的序列,所以srand产生的随机数是伪随机数。

如何用C语言生成随机矩阵 产生随机矩阵的关键是使用随机函数rand()。

兰德()

头文件:#includestdlib.h

定义函数:int rand(void)

功能描述:

因为rand的内部实现是用线性同余法做的,所以它不是真正的随机数,只是因为它的周期很长,所以在一定范围内可以看作是随机的,rand()会返回一个0到RAND_MAX范围内的随机值。在调用这个函数生成随机数之前,随机数种子必须由srand()设置。如果没有设置随机数种子,rand()在调用时会自动将随机数种子设置为1。Rand()产生一个伪随机数,每次执行都一样。为了与众不同,用不同的值初始化它。初始化的函数是srand()。

返回值:

返回0到RAND_MAX之间的随机整数值,RAND_MAX的范围至少在32767 (int)之间,即双字节(16位)。如果使用无符号整数,双字节是65535,四字节是4294967295的整数范围。

0~RAND_MAX每个数字被选中的概率是一样的。

基于随机函数,可以使用双环语句生成随机矩阵。以下是一个10x10随机矩阵的代码,数值范围为0~1000:

#包含stdio.h

#包含stdlib.h

#定义M 10

#定义N 10

int main(void)

{

int i = 0,j = 0;

int Arr[M][N]= { { 0 } };

srand(time(NULL));

for(I = 0;我是M;我)

{

for(j = 0;j N;j)

{

arr[I][j]= rand()% 1000;

}

}

printf("数组[%d][%d]为:\n ",M,N);

for(I = 0;我是M;我)

{

for(j = 0;j N;j)

{

printf("%d\t ",Arr[I][j]);

}

printf(" \ n ");

}

返回0;

}

C语言中的余数原理是什么?比如int X,y x-x/y * y = x% y。 剩余部分实际上是一个模块操作。

基础理论

基本概念:

给定正整数p和任意整数n,必有等式n = kpr

其中k和r是整数,0≤r ^ p,k是n除以p的商,r是n除以p的余数。

对于正整数p和整数a和b,定义了以下运算:

模运算:a% p(或一个模p),表示a除以p的余数。

模p加法:(a b)% p,结果是a b的算术和除以p的余数,即(a b) = kp r,则(ab)% 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。

!-【如果!supportLineBreakNewLine] -

!- [endif]

基本属性

(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,integer n

返回值:bool,如果整数n是偶数,则返回true,否则返回false。

*/

bool IsEven(int n)

{

return(n % 2 = = 0);

}

2.区分质数

如果一个数只有两个因子:1和它本身,则称它为素数(或素数)。比如2、3、5、7是质数,4、6、8、9不是。后者称为合数或合数。

判断自然数是否为素数最常用的方法是试除法:用小于自然数平方根的正整数除自然数,如果自然数能被整除,则说明它不是素数。

c实现功能函数:

/*

函数名:IsPrime

作用:判断自然数n是否为素数。

输入值:int n,自然数n

返回值:bool,如果自然数n是质数,则返回true,否则返回false。

*/

bool IsPrime(无符号整数n)

{

无符号max factor = sqrt(n);//n的最大因子

for(无符号int I = 2;i = maxFactor我)

{

如果(n% i == 0) //n能被I整除,那么n不是素数。

{

返回false

}

}

返回true

}

3.最大公约数

求最大公约数最常用的方法是欧几里德算法(也叫辗转除法),其计算原理依赖于定理:gcd(a,b) = gcd(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实现功能函数:

/*

函数:使用欧几里德算法,递归求两个自然数的最大公约数。

函数名:Gcd

输入值:无符号int a,自然数a。

无符号整数b,自然数b

返回值:无符号int,两个自然数的最大公约数。

*/

无符号整型Gcd(无符号整型a,无符号整型b)

{

如果(b == 0)

返回a;

返回Gcd(b,a % b);

}

/*

函数:利用欧几里德算法和迭代,求两个自然数的最大公约数函数名:Gcd。

输入值:无符号int a,自然数a。

无符号整数b,自然数b

返回值:无符号int,两个自然数的最大公约数。

*/

无符号整型Gcd(无符号整型a,无符号整型b)

{

无符号int temp

而(b!= 0)

{

temp = a % b;

a = b;

b =温度;

}

返回a;

}

4.模幂运算

利用模运算的运算规则,可以简化一些计算。比如我们想知道3333 5555的最后一位是什么?显然不可能直接算出3333 5555的结果,太大了。但是我们要确定的是3333 5555(),这样问题就简化了。

根据运算法则(4)ab% p = ((a% p)b)% p,我们知道3333 5555 () = 3 5555()。因为3 ^ 4 = 81,所以3 ^ 4()= 1。

根据运算规则(3) (a * b)% p = (a% p * b% p)% p,因为5555 = 4 * 1388 3,我们得到3 5555 () = (3 (4 * 1388) * 3 3) () =((。

=(1 * 7)()= 7。

计算完成。

使用这些规则,我们可以有效地计算X^N(% P。简单的算法是将结果初始化为1,然后将结果重复乘以x,并在每次相乘后应用%运算符(这使得结果的值更小以避免溢出)。N次相乘后,结果就是我们要找的答案。

这对于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(%。

函数名:PowerMod

输入值:无符号int x,base X。

无符号整数n,指数n

无符号整数p,模块p

返回值:无符号整数,X^N(% P)的结果

*/

无符号整数幂模(无符号整数x,无符号整数n,无符号整数p)

{

如果(n == 0)

{

返回1;

}

unsigned int temp = power mod((x * x)% p,n/2,p);//递归计算(x * x) [n/2]

if((n ^ 1)!= 0) //判断n的奇偶性

{

temp =(temp * x)% p;

}

返回温度;

}

5.孙子问题(中国的剩余定理)

中国古代孙子的计算中有这样一个问题:

“我不知道今天的事情的数量。三三两两,五五两,七七两。事物的几何是什么?”意思是,“一个数除以3大于2,除以5大于3,除以7大于2。找到适合这个条件的最小数。”

这个问题被称为“孙子问题”。孙子问题的通解在国际上被称为“中国剩余定理”。

中国古代学者早就研究过这个问题。例如,中国明代数学家程大伟在他的著作《算术统一》(1593年)中用四个非常流行的公式暗示了这个问题的解决方法:

三个人瘦了七十倍,五树梅花一枝香,七个孩子团聚半个月,除了一百零五。

“满月”意味着15。“除以105”的本意是当数大于105时,再减去105,105使之小于105;这相当于除以105,求余数。

这四个公式暗示,当除数分别为3、5、7时,将70乘以余数除以3,将21乘以余数除以5,将15乘以余数除以7,然后将三个乘积相加。如果相加的结果大于105,除以105,余数就是满足题目要求的最小正整数解。

根据余数定理,我把这个解推广到有n个除数对应n个余数的情况,求最小被除数。输入n个除数(除数不能互相整除)和对应的余数,计算机会输出最小的被除数。

c实现功能函数:

/*

函数名:ResidueTheorem

函数:利用余数定理解决扩展孙子问题。给定n个除数(除数不能互相整除)和相应的余数,返回最小被除数。

输入值:unsigned int devisor[],存储n个除数的数组。

无符号int survivor [],存储n个余数的数组。

Int length,数组的长度

返回值:无符号整数,最小被除数。

*/

unsigned int residue Orem(const unsigned int devisor[],const unsigned int remainder[],int length)

{

无符号整数乘积= 1;//所有除数的乘积

for(int I = 0;ilengthI )//计算所有除数的乘积。

{

product * = deviser[I];

}

//公倍数数组,表示除此元素(除数)以外的除数的公倍数

unsigned int * common multiple = new unsigned int(length);

for(int I = 0;ilengthI )//计算元素(除数)以外的约数的公倍数

{

common multiple[I]= product/deviser[I];

}

无符号int被除数= 0;//Divider是函数要返回的值。

for(int I = 0;ilengthI )//计算股息,但不是最低股息。

{

unsigned int tempMul = common multiple[I];

//根据留数理论计算适当的公倍数,使tempMul% devisor[i] == 1。

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

{

tempMul = common multiple[I];

}

股息= tempMul *余数[I];//将这个除数得到的余数乘以其他除数的公倍数。

}

删除[]common multiple;

回报(股息%乘积);//返回最小的红利

}

6.凯撒密码

凯撒密码(Caesar)是罗马扩张时期朱利叶斯·凯撒(Julius Caesar)创造的,用于加密信使传递的作战命令。

它将字母表中的字母移动到一定位置,实现加密。注意26个字母循环使用,z可以称为a。

举个例子,当密钥为k = 3,也就是后移3位,如果明文是“你好!”,密文是“Krz duh btx!”。

凯撒密码的加密算法极其简单。加密过程如下:

这里我们做这个约定:明文标记为m,密文标记为c,加密变换标记为E(key1,m)(其中key1为密钥)。

解密变换表示为D(key2,m)(key2是解密密钥)(这里key1=key2,所以可以表示为key)。

凯撒密码的加密过程可以描述为如下变换:c≡m key (mod n)(其中n为基本字符数)。

同样,解密过程可以表示为m≡c key (mod n)(其中n为基本字符数)。

c实现功能函数:

/*

函数:利用凯撒密码原理加密明文,返回密文函数名:Encrypt。

输入值:const char proclaimedInWriting[],存储明文字符串。

Char密文[],用来存储密文的字符串。

Int keyey,加密密钥,正数表示向后,负数表示向前。

返回值:没有返回值,但是应该返回一个新的密文字符串。

*/

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

{

const int NUM = 26//字母数

int len = strlen(proclaimedInWriting);

for(int I = 0;ilen我)

{

if(宣告书写[i] = 'a '宣告书写[i] = 'z ')

{//如果明码是大写,那么密码也是大写。

密文[I]=(proclaimedInWriting[I]-' a ' key)% NUM ' a ';

}

else if(宣告书写[i] = 'A '宣告书写[i] = 'Z ')

{//如果明码是小写的,密码也是小写的。

密文[I]=(proclaimedInWriting[I]-' A ' key)% NUM ' A ';

}

其他

{//明码不是字母,所以密码和明码一样。

密码[i] =宣告书写[I];

}

}

密文[len]= ' \ 0 ';

}

/*

函数:利用凯撒密码原理解密密文,返回明文函数名:Decode。

输入值:char proclaimedInWriting[],用于存储明文字符串。

Const char密文[],存储密文的字符串。

Int keyey,解密密钥,正数表示向前,负数表示向后(与加密相对)。

返回值:没有返回值,但是应该返回一个新的明文字符串。

*/

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

{

const int NUM = 26//字母数

int len = strlen(密文);

for(int I = 0;ilen我)

{

if(密文[i] = 'a '密文[i] = 'z ')

{//如果密码是大写字母,明码也是大写字母。要防止负数,请在转换时添加一个数字。

proclaimedInWriting[I]=(cryptographic[I]-' a '-key NUM)% NUM ' a ';

}

else if(密文[i] = 'A '密文[i] = 'Z ')

{//如果密码是小写的,明码也是小写的。

proclaimedInWriting[I]=(cryptographic[I]-' A '-key NUM)% NUM ' A ';

}

其他

{//如果密码不是字母,则明码与明码相同。

宣告书写[i] =密码[I];

}

}

宣告正在编写[len]= ' \ 0 ';

}

在C语言中,0%2= 0%2= 0 。

在C语言中,这是一种模运算,定义如下:

给定一个正整数p和任意整数n,必然有一个等式:

n = KP r;

其中k和r都是整数,0≤r ^ p,那么k叫做n除以p的商,r是n除以p的余数。

对于正整数p和整数a和b,定义了以下运算:

模运算:a% p(或一个模p),表示a除以p的余数。

问题中,a=0,p=2,所以0除以2的余数是0。

扩展数据:

“模运算”和“互补”这两个概念有重叠,但并不完全一致。主要区别在于负整数除法时的运算不同。

模块化主要用于计算机术语。余数更多的是一个数学概念。模运算在数论和编程中有着广泛的应用,从奇偶数的判别到质数的判别,从模幂运算到最大公约数的求解,从孙子问题到凯撒密码问题,无一不是充满了模运算。

虽然很多数论教材都在一定程度上介绍了模运算,但大部分都是基于纯理论,模运算在编程中的应用涉及不多。

参考来源:百度百科-模块化运营

用乘法和同余在C语言中生成随机数? c语言有一个特定的生成随机数的语法。以下是一个完整的改变随机数的程序:# incl dues dio . h # include time . hmain(){ int x;srand((无符号)时间(空));//将变化的系统时间作为随机种子x = rand()% 6 1;//获取一个封闭区间[1,6]的随机数,这里可以设置自己的printf("%d\n ",x);返回0;}

相关文章

发表新评论