gpt4 book ai didi

c - 如何在C中使用rand()生成0001-2000范围内的唯一数字

转载 作者:太空宇宙 更新时间:2023-11-03 23:39:43 25 4
gpt4 key购买 nike

我正在尝试生成一个包含这两项的数据集:(I)包含随机生成的值(0001到2000)的学生ID;(ii)与学生ID相对应的年龄(18到30)这些随机值保存在各自的数组[1000]中,如代码中所示
我遇到了rand()的问题,在这里我指定要为学生ID从1到2000生成随机数,但我遇到了我认为是整数溢出的问题我认为这些问题可能来自以下某个方面:
我的函数是int类型的,我可能需要尝试其他类型?
我实现rand()%声明的方式有问题
其他一些我不知道的问题
你可以看到我在输出中遇到的问题
代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int createDataSet(void)
{
srand(time(NULL)); // generates the random numbers

int i = 0, x, p, count;

char arrayId[1000]; // array that holds the ID's of 1000 students
char arrayAges[1000]; // array that holds the ages of 1000 students

for (count = 0; count < 1000; count++) // Init the "age" and "id" arrays
{
arrayId[count] = rand() % 2000 + 1; // ID range 0001 - 2000
arrayAges[count] = rand() % (30 + 1 - 18) + 18; // Age range 18 - 30
}

while(i<1000){
int r=rand() % (2000 + 1 - 0001) + 0001;

for (x = 0; x < i; x++)
{
if(arrayId[x]==r){
break;
}
}
if(x==i){
arrayId[i++]=r;
}
}

for (p = 0; p < 1000; p++)
{
printf("ID Number: %d Age: %d\n", arrayId[p], arrayAges[p]);
}
return 0;
}

输出:
ID Number: 115       Age: 28
ID Number: 104 Age: 21
ID Number: -113 Age: 25
ID Number: -3 Age: 18
ID Number: -41 Age: 20
ID Number: -94 Age: 28
ID Number: -4 Age: 19
ID Number: 4 Age: 28
ID Number: -112 Age: 23
ID Number: 33 Age: 20
ID Number: -119 Age: 30
ID Number: 12 Age: 23
ID Number: -96 Age: 27
ID Number: -88 Age: 30
ID Number: -105 Age: 20

我的目标是尝试在数组中获取ID Number中的值:显示1到2000之间的随机值,并且是无符号类型如有任何帮助,我们将不胜感激谢谢你的时间!

最佳答案

虽然对于试图将char范围之外的整数值赋给char变量的初始问题,您已经有了一个很好的答案,但仍有许多小问题没有得到解决。
首先,不要在代码中使用幻数如果需要常量,可以使用#define或全局enum来定义它们,例如。

/* if you need a constants, define them */
enum { MINA = 18, MAXA = 30, MAXS = 1000, MAXID = 2000 };

(其中 MINAMINIMUMAGE的缩写, MAXSMAXIMUMSTUDENTS的缩写,等等)
这样,如果需要更改范围或限制,则在代码顶部有一个简单的位置进行更改,而不必选择所有循环限制和变量声明。
接下来, return 0;中的 createDataset没有意义如果您没有要返回的值,并且您没有在函数中执行任何需要返回以衡量成功/失败的操作,则将您的函数声明为 void同样,该函数可能会生成一个数据集并将值打印到 stdout,但如果代码的其余部分需要该数据集,则无法使用它为什么?所有数组 char arrayId[]..都声明为函数的本地数组,当函数返回时,它们存储的内存将被销毁(释放以供重用)您可能需要重构代码以在 main()中声明数组,并将数组以及元素的数量传递给函数进行初始化。
您可以在函数中使用此临时存储,以防止重复的id您可以简单地声明一个长度为 MAXID的字符数组(例如 char filled[MAXID] = "";),初始化为所有零,并且在生成每个对应的ID时,将该索引处的值设置为 1(或一些非零值)这使得重复检查成为一个简单的 if (filled[r]) { /* regenerate ID */ }
考虑重构代码时,需要将每个函数的函数分离为逻辑单元您的生成ID/age和输出组合可能适合您的当前需要,但是请考虑将生成函数和输出分离为单独的函数。
虽然不是错误,但C的标准编码样式避免了使用 camelCaseMixedCase变量名,而是使用所有小写,同时保留大写名称以用于宏和常量这是一个风格问题——所以完全取决于你,但如果你不遵循它,可能会在某些圈子里给人留下错误的第一印象。
将这些部分组合在一起,可以将当前函数重构为单独的生成和打印函数,如下所示:
void createdataset (unsigned short *ids, char *ages, int count)
{
char filled[MAXID] = {0}; /* array preventing duplicates */

for (count = 0; count < MAXS; count++) /* for each student */
{
/* generate an ID */
unsigned short r = (unsigned short)(rand() % MAXID + 1);
while (filled[r]) /* while a duplicate, regenerate */
r = (unsigned short)(rand() % MAXID + 1);
filled[r] = 1; /* set filled[index] to 1 */
ids[count] = r; /* assign ID to student */
ages[count] = (char)(rand() % (MAXA - MINA + 1) + MINA);
}
}

void prndataset (unsigned short *ids, char *ages, int count)
{
int i = 0;

for (i = 0; i < count; i++)
printf ("ID Number: %4hu Age: %2hhd\n", ids[i], ages[i]);
}

注意: srand在代码中只应调用一次因此,如果可能生成多个数据集,则应将其放置在 main()中,以确保只调用一次。
当您开发的代码必须满足特殊条件时,比如id介于 1-2000和age介于 18-30之间时,请考虑编写一个简单的验证检查,以验证所有值都在范围内例如,您可以在这里执行以下操作:
int validateset (unsigned short *ids, char *ages, int count)
{
int i = 0, err = 0;

for (i = 0; i < count; i++) {
if (ids[i] < 1 || ids[i] > MAXID) {
fprintf (stderr, "error: arrayid[%d] : %hu out of range.\n",
i, ids[i]);
err = 1;
}
if (ages[i] < MINA || ages[i] > MAXA) {
fprintf (stderr, "error: arrayages[%d] : %hhd out of range.\n",
i, ages[i]);
err = 1;
}
}

return err;
}

(如果成功,则返回 0,如果在输出任何违规值后有任何值超出范围,则返回 1
此外,在打印值时,请确保格式说明符与要输出的值类型匹配虽然提升规则将处理使用 shortint格式说明符将较小的值(例如 %d)转换为 %u,但如果编译器支持 h修饰符,则应使用它们指定适当的输出大小(例如,要打印 unsigned short,请使用 %hu或打印 unsigned char,请使用 %hhu)。
将所有部分放在一个简短的示例中,您可以重构代码并添加一个验证检查,其内容类似于以下内容:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/* if you need a constants, define them */
enum { MINA = 18, MAXA = 30, MAXS = 1000, MAXID = 2000 };

void createdataset (unsigned short *ids, char *ages, int count)
{
char filled[MAXID] = {0}; /* array preventing duplicates */

for (count = 0; count < MAXS; count++) /* for each student */
{
/* generate an ID */
unsigned short r = (unsigned short)(rand() % MAXID + 1);
while (filled[r]) /* while a duplicate, regenerate */
r = (unsigned short)(rand() % MAXID + 1);
filled[r] = 1; /* set filled[index] to 1 */
ids[count] = r; /* assign ID to student */
ages[count] = (char)(rand() % (MAXA - MINA + 1) + MINA);
}
}

void prndataset (unsigned short *ids, char *ages, int count)
{
int i = 0;

for (i = 0; i < count; i++)
printf ("ID Number: %4hu Age: %2hhd\n", ids[i], ages[i]);
}

int validateset (unsigned short *ids, char *ages, int count)
{
int i = 0, err = 0;

for (i = 0; i < count; i++) {
if (ids[i] < 1 || ids[i] > MAXID) {
fprintf (stderr, "error: arrayid[%d] : %hu out of range.\n",
i, ids[i]);
err = 1;
}
if (ages[i] < MINA || ages[i] > MAXA) {
fprintf (stderr, "error: arrayages[%d] : %hhd out of range.\n",
i, ages[i]);
err = 1;
}
}

return err;
}

int main (void) {

unsigned short arrayid[MAXS] = {0}; /* size your type to your needed */
char arrayages[MAXS] = {0}; /* range and enforce the range */

srand(time(NULL)); /* initialize random number seed */

createdataset (arrayid, arrayages, MAXS); /* initialize dataset */
if (validateset (arrayid, arrayages, MAXS)) /* validate dataset */
exit (EXIT_FAILURE);
prndataset (arrayid, arrayages, MAXS); /* output dataset */

return 0;
}

(通过添加验证检查,您可以确信如果代码运行时没有显示错误,则数据集生成正确)
示例使用/输出
$ ./bin/createdataset > dat/dataset1.txt

$ head -n 10 dat/dataset1.txt; echo "..."; tail -n 10 dat/dataset1.txt
ID Number: 1049 Age: 29
ID Number: 743 Age: 21
ID Number: 915 Age: 22
ID Number: 1539 Age: 19
ID Number: 793 Age: 18
ID Number: 1166 Age: 21
ID Number: 372 Age: 28
ID Number: 1763 Age: 19
ID Number: 782 Age: 20
ID Number: 1490 Age: 30
...
ID Number: 186 Age: 30
ID Number: 1389 Age: 23
ID Number: 1630 Age: 22
ID Number: 432 Age: 27
ID Number: 240 Age: 24
ID Number: 152 Age: 25
ID Number: 1598 Age: 22
ID Number: 1408 Age: 24
ID Number: 834 Age: 24
ID Number: 1699 Age: 25

虽然您的主要问题是存储cc中的cc,但还有许多更微妙的问题需要考虑。再看一遍,如果你还有什么问题,请告诉我。

关于c - 如何在C中使用rand()生成0001-2000范围内的唯一数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49216437/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com