c语言同余法

(C语言)线性同余产生随机数的问题。 线性同余随机数发生器是按Xn+1 = (aXn+c)%m

这题你可以直接全部算就行了,要记录下每一次算出来的结果,如果算出来的结果是已经产生过的,那就证明陷入循环了,不能产生所以的0~m-1的数,如果全部找到都还没有算出重复的,那就说明可以产生所有数

c语言同余法

C语言中rand()%m是啥意思?

rand()%m这个函数是随机产生0到m-1的随机数;比如rand()%10就是随机产生0到9的随机数。

拓展资料

使用C语言的rand函数,生成的是伪随机数;

c语言之rand函数的使用

1、写入头文件

2、变量的定义

3、srand( (unsigned)time( NULL ) ); /*选取种子文件*/

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

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

(1)此为随机函数的一种产生方法

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

生成随机数rand函数的用法:

函数rand()是真正的随机数生成器,而srand()会设置供rand()使用的随机数种子。如果你在第一次调用rand()之前没有调用srand(),那么系统会为你自动调用srand()。而使用同种子相同的数调用 srand()会导致相同的随机数序列被生成。

srand((unsigned)time(NULL))则使用系统定时/计数器的值做为随机种子。每个种子对应一组根据算法预先生成的随机数,所以,在相同的平台环境下,不同时间产生的随机数会是不同的,相应的,若将srand(unsigned)time(NULL)改为srand(TP)(TP为任一常量),则无论何时运行、运行多少次得到的“随机数”都会是一组固定的序列,因此srand生成的随机数是伪随机数。

C语言如何生成一个随机矩阵

生产随机的矩阵的关键在于使用随机函数rand()。

rand()

表头文件: #includestdlib.h

定义函数 :int rand(void)

函数说明 :

因为rand的内部实现是用线性同余法做的,他不是真的随机数,只不过是因为其周期特别长,所以有一定的范围里可看成是随机的,rand()会返回一随机数值,范围在0至RAND_MAX 间。在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。rand ()产生的是假随机数字,每次执行时是相同的。若要不同,以不同的值来初始化它.初始化的函数就是srand()。

返回值:

返回0至RAND_MAX之间的随机整数值,RAND_MAX的范围最少是在32767之间(int),即双字节(16位数)。若用unsigned int 双字节是65535,四字节是4294967295的整数范围。

0~RAND_MAX每个数字被选中的机率是相同的.

基于随机函数,使用双重循环语句便可以生成一个随机矩阵,下面是一个10×10随机矩阵的代码,数值范围在0~1000:

#include stdio.h                     

#include stdlib.h                    

                                               

#define M 10                           

#define N 10                           

                                               

int main(void)                         

{                                      

    int i = 0, j = 0;                  

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

                                               

    srand(time(NULL));                 

                                               

    for (i = 0; i  M; ++i)            

    {                                  

        for (j = 0; j  N; ++j)        

        {                              

            Arr[i][j] = rand() % 1000; 

        }                              

    }                                  

                                               

    printf(“Array[%d][%d] is: \n”, M, N);

    for (i = 0; i  M; ++i)            

    {                                  

        for (j = 0; j  N; ++j)        

        {                              

            printf(“%d\t”, Arr[i][j]); 

        }                              

        printf(“\n”);                  

    }                                  

    return 0;                          

}

C语言取余的原理是怎么回事? 比如 int X,Y X-X/Y*Y=x%y

取余实际上就是模运算

基本理论

基本概念:

给定一个正整数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。

!–[if !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,整数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(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

假设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

输入值: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;

}

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)

{

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.《孙子问题(中国剩余定理)》

在我国古代算书《孙子算经》中有这样一个问题:

“今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?”意思是,“一个数除以3余2,除以5余3,除以7余2.求适合这个条件的最小数。”

这个问题称为“孙子问题”.关于孙子问题的一般解法,国际上称为“中国剩余定理”.

我国古代学者早就研究过这个问题。例如我国明朝数学家程大位在他著的《算法统宗》(1593年)中就用四句很通俗的口诀暗示了此题的解法:

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

“正半月”暗指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)

{

unsigned int product = 1; //所有除数之乘积

for (int i=0; ilength; i++)//计算所有除数之乘积

{

product *= devisor[i];

}

//公倍数数组,表示除该元素(除数)之外其他除数的公倍数

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

for (int i=0; ilength; i++)//计算除该元素(除数)之外其他除数的公倍数

{

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

}

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

for (int i=0; ilength; 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)。

凯撒密码的加密过程可记为如下一个变换:c≡m+key (mod n) (其中n为基本字符个数)

同样,解密过程可表示为:m≡c+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; ilen; 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; ilen; 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’;

}

在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(或a mod p),表示a除以p的余数。

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

扩展资料:

取模运算(“Modulo Operation”)和取余运算(“Complementation ”)两个概念有重叠的部分但又不完全一致。主要的区别在于对负整数进行除法运算时操作不同。

取模主要是用于计算机术语中。取余则更多是数学概念。模运算在数论和程序设计中都有着广泛的应用,从奇偶数的判别到素数的判别,从模幂运算到最大公约数的求法,从孙子问题到凯撒密码问题,无不充斥着模运算的身影。

虽然很多数论教材上对模运算都有一定的介绍,但多数都是以纯理论为主,对于模运算在程序设计中的应用涉及不多。

参考资料来源:百度百科-取模运算

在c语言中采用乘同余方法产生随机数?

C语言产生随机数有特定的语法,下面的是变化随机数的完整程序:#inclduestdio.h#includetime.hmain(){int x;srand((unsigned)time(NULL));//以不断变化的系统时间作为随机种子x=rand()%6+1;//获取闭区间【1,6】的随机一个数,这里可以自己设定printf(“%d\n”,x);return 0;}

本文来自投稿,不代表【】观点,发布者:【

本文地址: ,如若转载,请注明出处!

举报投诉邮箱:253000106@qq.com

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2024年3月25日 16:31:01
下一篇 2024年3月25日 16:38:23

相关推荐

  • c语言改写模式,c语言实现修改功能

    c语言程序修改? 1、这个程序有4个错误,我都加粗了,第一个是m没有赋初值,第二个是while表达式中的ch=getchar()需要括号括起来,第三个是m=m*10+ch-0中的0也需要用单引号括起来,第四个是第2个while中为m!=0。 2、define容易造成误会,因为不符合一般的编程习惯,false 0, true 1;scanf放在你的那个地方是达…

    2024年5月23日
    4100
  • c语言控制代码的换码序列,c语言交换代码

    求C语言编程大神解答一下下面这个编程代码? k==5,用5去除125余0,所以r=125%5中r为0。由于!0为1,所以执行while循环体:先打印出5(k的值),再n=n/k==125/5=25;由于251则再打印出*号。这一循环结果输出是5*。 下面是我的代码,三个函数分别对应三个问题。 在实现基本要求的前提下,拓展了可以从键盘输入的功能,以下为各题代码…

    2024年5月23日
    5800
  • c语言扫描io脚状态,c语言端口扫描

    求51单片机的上升沿和下降沿C语言检测程序列子,端口就是普通IO口。 上升沿触发是当信号有上升沿时的开关动作,当电位由低变高而触发输出变化的就叫上升沿触发。也就是当测到的信号电位是从低到高也就是上升时就触发,叫做上升沿触发。 单片机怎么计算1s内下降沿的个数的C语言程序或者计算两个下降沿的时间(检测脉冲频率)计算1s内下降沿的个数方法是,一个定时器设置定时1…

    2024年5月23日
    4500
  • c语言mallloc使用的简单介绍

    C语言中使用malloc必须加#includemallo.h? 1、在C语言中使用malloc函数进行动态内存分配。malloc的全称是memory allocation,中文叫动态内存分配。原型:extern void malloc(unsigned int num_bytes);功能:分配长度为num_bytes字节的内存块。 2、你可以看一下C语言那本…

    2024年5月23日
    4500
  • c语言三位小数,C语言三位小数

    怎样用C++语言输出精确到小数点后三位的数? 1、用C++语言输出精确到小数点后三位的数,可以参考下面给出的代码:coutsetiosflags(ios:fixed)setprecision(3)。其中 setiosflags中set是设置的意思。ios是iostream的缩写,即输入输出流。flags是标志的意思。 2、要精确到小数点后若干位,则数据类型为…

    2024年5月23日
    7500
  • c语言21点游戏,二十一点游戏代码c语言

    如何使用C语言编写简单小游戏? 1、数学知识:长方形的面积S=a*b 长方形周长L=2*(a+b)其中a b分别为长方形的宽和高。算法分析:长方形面积及周长均依赖于宽和高,所以先要输入宽高值,然后根据公式计算,输出结果即可。 2、/*也不知道你是什么级别的,我是一个新手,刚接触编程语言,以下是我自己变得一个小程序,在所有c语言的编译器(vc++0、turbo…

    2024年5月23日
    6500
  • c语言当中的null,C语言当中的符号

    C/C++中,NULL和null的区别是什么? nul 和 null要看编译器,不同的编译器有所区别。 所以C或者C++中都使用一个特殊定义NULL表示无效值,其本质就是未定义具体数据类型的0值。 null是是什么都没有的意思。在java中表示空对象。 本意是“空的;元素只有零的”意思。计算机中通常表示空值,无结果,或是空集合。\x0d\x0a在ASCII码…

    2024年5月23日
    4700
  • 包含c语言对txt文件命名的词条

    如何在C语言编程里面修改源文件名字 如果你是在WINDOWS的话,简单了,随便用个编辑器,比如记事本,然后写c源程序,保存到你想要保存的位置。如果你在DOS下,可以用edit,写好以后,按alt键,选择文件菜单,然后保存。 用open打开文件,注意操作模式使用“修改”或者“添加” 用write或者fprintf向文件中写入你的内容。 用close关闭文件。 …

    2024年5月23日
    5000
  • 学c语言编程,学c语言编程用什么软件

    编程开发必须要学C语言吗? 1、要学习。编程开发的学习内容主要包括c语言、python和c+语言。C语言作为一种简单灵活的高级编程语言,它是一个面向过程的语言,一般是作为计算机专业的基础入门语言课程。 2、C语言。对于刚接触编程的人来说,先学习C语言是非常重要的。C语言可以说是是计算机编程语言的鼻祖,其他的编程语言几乎全是由C语言变化衍生出来的。 3、不需要…

    2024年5月23日
    3500
  • c语言用string定义字符串,c语言中用string类型来处理字符串类型

    C++怎样定义定义字符串 1、第一是字符数组来表示字符串。用下面的语句声明:char a[10];C语言中字符数组与字符串的唯一区别是字符串末尾有一个结束符\0,而字符数组不需要。 2、在C中定义字符串有下列几种形式:字符串常量,char数组,char指针 字符串常量 即:位于一对双括号中的任何字符。双引号里的字符加上编译器自动提供的结束标志\0字符,作为 …

    2024年5月23日
    4500

发表回复

登录后才能评论



关注微信