如何在每个数字都非零的 C 中生成随机 long int?而且随机数在重复
How to generate random long int in C where every digit is non-zero? Moreover the random numbers are repeating
我正在用 C 编写库管理以供练习。现在,在 studentEntry 中,我需要生成一个 long int studentID,其中每个数字都不为零。所以,我正在使用这个函数:
long int generateStudentID(){
srand(time(NULL));
long int n = 0;
do
{
n = rand() % 10;
}while(n == 0);
int i;
for(i = 1; i < 10; i++)
{
n *= 10;
n += rand() % 10;
}
if(n < 0)
n = n * (-1); //StudentID will be positive
return n;
}
输出
Name : khushit
phone No. : 987546321
active : 1
login : 0
StudentID : 2038393052
Wanted to add another student?(y/n)
我想从中删除所有零。此外,当我 运行 程序第一次随机数将与上面相同,第二次随机数与过去 运行s 相同,例如:-
程序运行1
StudentID : 2038393052
StudentID : 3436731238
节目运行2
StudentID : 2038393052
StudentID : 3436731238
我需要什么来解决这些问题?
稍微修改一下您的原始函数的执行顺序。不要删除 0,而不要添加 0。
long int generateStudentID(){
srand(time(NULL));
long int n = 0;
for(int i = 0; i < 10; i++)
{
long int m = 0;
do
{
m = rand() % 10;
}while(m == 0);
n *= 10;
n += m;
}
//Not needed as n won't be negative
//if(n < 0)
//n = n * (-1); //StudentID will be positive
return n;
}
您可以按照 gchen 的建议进行 运行 一个小循环,一直持续到结果不为零(就像您对第一个数字所做的那样),或者接受一个小偏差并使用 rand() % 9 + 1
.
相似序列的问题与time()
的粗分辨率有关。如果您 运行 在第一次调用后快速调用该函数,您将获得相同的种子。您可能会阅读 user3386109 在评论中提出的 this description。
可以通过以下方式生成数字中没有零的九位数学生证:
long generateStudentID(void)
{
long n = 0;
for (int i = 0; i < 9; i++)
n = n * 10 + (rand() % 9) + 1;
return n;
}
这通过使用 (rand() % 9)
生成 0 到 8 之间的数字并加 1 来生成 1 到 9 之间的随机数字。不需要 for 循环来避免零。
请注意,这不会调用 srand()
— 您应该在给定程序中调用 only call srand()
once(在正常情况下)。由于long
必须至少有32位,而9位数字只需要30位,所以不用担心溢出。
可以说结果略微偏向于较小的数字。您可以使用函数调用来消除这种偏差:
int unbiassed_random_int(int max)
{
int limit = RAND_MAX - RAND_MAX % max;
int value;
while ((value = rand()) >= limit)
;
return value % max;
}
若RAND_MAX为32767,max
为9,则RAND_MAX % 9
为7。如果不忽略32760以上的数值,则更有可能得到一个数字在 0..7 的范围内比你得到 8 的范围要多——0..7 有 3642 种方法,而得到 8 只有 3641 种方法。差别不大;如果 RAND_MAX 更大,它会更小。对于手头的目的,没有必要进行这种细化。
我正在用 C 编写库管理以供练习。现在,在 studentEntry 中,我需要生成一个 long int studentID,其中每个数字都不为零。所以,我正在使用这个函数:
long int generateStudentID(){
srand(time(NULL));
long int n = 0;
do
{
n = rand() % 10;
}while(n == 0);
int i;
for(i = 1; i < 10; i++)
{
n *= 10;
n += rand() % 10;
}
if(n < 0)
n = n * (-1); //StudentID will be positive
return n;
}
输出
Name : khushit
phone No. : 987546321
active : 1
login : 0
StudentID : 2038393052
Wanted to add another student?(y/n)
我想从中删除所有零。此外,当我 运行 程序第一次随机数将与上面相同,第二次随机数与过去 运行s 相同,例如:-
程序运行1
StudentID : 2038393052
StudentID : 3436731238
节目运行2
StudentID : 2038393052
StudentID : 3436731238
我需要什么来解决这些问题?
稍微修改一下您的原始函数的执行顺序。不要删除 0,而不要添加 0。
long int generateStudentID(){
srand(time(NULL));
long int n = 0;
for(int i = 0; i < 10; i++)
{
long int m = 0;
do
{
m = rand() % 10;
}while(m == 0);
n *= 10;
n += m;
}
//Not needed as n won't be negative
//if(n < 0)
//n = n * (-1); //StudentID will be positive
return n;
}
您可以按照 gchen 的建议进行 运行 一个小循环,一直持续到结果不为零(就像您对第一个数字所做的那样),或者接受一个小偏差并使用 rand() % 9 + 1
.
相似序列的问题与time()
的粗分辨率有关。如果您 运行 在第一次调用后快速调用该函数,您将获得相同的种子。您可能会阅读 user3386109 在评论中提出的 this description。
可以通过以下方式生成数字中没有零的九位数学生证:
long generateStudentID(void)
{
long n = 0;
for (int i = 0; i < 9; i++)
n = n * 10 + (rand() % 9) + 1;
return n;
}
这通过使用 (rand() % 9)
生成 0 到 8 之间的数字并加 1 来生成 1 到 9 之间的随机数字。不需要 for 循环来避免零。
请注意,这不会调用 srand()
— 您应该在给定程序中调用 only call srand()
once(在正常情况下)。由于long
必须至少有32位,而9位数字只需要30位,所以不用担心溢出。
可以说结果略微偏向于较小的数字。您可以使用函数调用来消除这种偏差:
int unbiassed_random_int(int max)
{
int limit = RAND_MAX - RAND_MAX % max;
int value;
while ((value = rand()) >= limit)
;
return value % max;
}
若RAND_MAX为32767,max
为9,则RAND_MAX % 9
为7。如果不忽略32760以上的数值,则更有可能得到一个数字在 0..7 的范围内比你得到 8 的范围要多——0..7 有 3642 种方法,而得到 8 只有 3641 种方法。差别不大;如果 RAND_MAX 更大,它会更小。对于手头的目的,没有必要进行这种细化。