c语言随机生成带符号的int并填充数组,检查是否有重复,挂在32768

迈克尔·威廉姆斯

首先,有一点背景。我是Compsci的电气工程专业的学生,​​我几乎完全是自学成才,几乎没有经过严格的编程培训,因此下面的代码中可能存在一些不“标准”的内容。

这个小程序只是一个实用程序,用于生成任意大小的数据文件,该文件填充有随机生成的带符号的int值,以用作分配的输入。我已经完成任务,并且工作正常。这是一个关于这个程序中发生的奇怪事情的问题,对我而言,这只是在我添加代码部分以检查重复项时才开始发生的。以前,它只是将整数直接转储到一个文件中,每行一个。然后,我意识到这并不是教授数据的严格格式化方式,因此我进行了更改以防止重复,每行添加多个int并添加其他空格分隔符(空格,制表符,换行符)。

好的,所有这些都说明了,只要我将MAX_NUMBERS保持在32k或更低,它就可以工作。如果我提高它,它会很好地显示计数,直到大约32k左右,然后它减慢几百个左右,然后突然挂在32768。由于这个数字,我认为可能必须这样做具有int的大小(在ming编译器中使用代码块),但是sizeof(int)显示它为4个字节,因此不应该引起它。还以为我可能在未使用数组之前就达到了数组索引数量的最大限制。我的研究表明,这不应该是原因。我知道随着要检查重复项的值数量的增加,它的速度将会降低,但是我很困惑为什么它突然停止。

最后,作为实验,我确实尝试将其修改为使用更大的C99数据类型而不是int,但这没有任何作用。

如果有人碰巧看到任何愚蠢的东西,除了使用数组哈哈,请告诉我!这让我有些疯狂。

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


int main()
{
    const int MAX_NUMBERS = 32000; // don't go higher than about 32000
    int* arr;
    // arr is used for duplicate checking, a log of everything put into the file is recorded
    // in arr and checked against to ensure uniqueness.

    const int ALLOW_NEG = 1; // switch to choose whether to allow negative numbers or not.

    int x = 0; // the random number that was generated
    int index = 0; // main loop control
    int index2 = 0; // dupe check loop control
    int hpos = 1; // used to select which type of whitespace to add
    int uniNum = 1; // uniqueness flag
    FILE *f = fopen("nums.txt", "w"); // open the file for writing. creates it if it's not there.

    arr = calloc(MAX_NUMBERS, sizeof(int)); // allocate space for the array

    for (index = 0; index < MAX_NUMBERS; index++) // arr init loop
        arr[index] = 999999999; // init the array to an invalid value. initially was 0, but caused 0 to be omitted by the dupe checker


    if (f == NULL){ // sanity check for the file
        printf("Error: Unable to open file. Program aborting.\n");
        exit(1);
    }

    printf("Generating data file...\n");

    srand(time(NULL)); // seed the random number generator

    fprintf(f, "%d\n", MAX_NUMBERS); // write the first line, the total number of ints in the file

    for (index = 0; index < MAX_NUMBERS; index++) { // main loop
        printf("\r%d", index); // just a display of the indices as the loops running, useless for small counts, semi-useful for very large amounts (100k+)
        do { // check for unique number
            uniNum = 1; // set uniqueness flag
            if (ALLOW_NEG == 1) { // executed if negatives are allowed
                  // This will allow 0, which makes sens if the
                  // range includes negative and positive.
                x = (rand() % MAX_NUMBERS+1) -((MAX_NUMBERS+1)/2); // generate a random number between (-max_nums/2) and (max_nums/2), totaling max_nums. the +1 is a bug fix, ask if curious
            } else { // no negs allowed!
                 // +1 makes the range from 1 to MAX_NUMBERS + 1,
                 // change to zero or remove to range from 0 to MAX_NUMBERS
                x = (rand() % MAX_NUMBERS+1) + 1; // generate random number of only positive ints and 0.
            }

            for (index2 = 0;index2 <= index; index2++){ // check currently generated numbers for dupes
                if (x == arr[index2]) { // dupe found!
                    uniNum = 0; // clear uniqueness flag
                    break; // end the for loop on a dupe, no sense in continuing
                }
            }
        } while(uniNum != 1); // repeat if the number wasn't unique
        arr[index] = x; // log the number

        if (hpos > 4) { // check to see if the horizontal position indicator is greater than 4
            fprintf(f, "%d\n", x); // write to the 5th position horizontally with a newline
            hpos = 1; // reset the horizontal position to the first. this gives me 5 numbers
                      //per line, with differing types of whitespace, just to test the reading
                      //and storing function. see a2.txt
        } else {
            switch (hpos) { // select based on which position we are in
                case 1 :
                    fprintf(f, "%d ", x); // first, space
                    hpos++;
                break;
                case 2 :
                    fprintf(f, "%d\t", x); // second, a tab character
                    hpos++;
                break;
                case 3 :
                    fprintf(f, "%d ", x); // third, another space
                    hpos++;
                break;
                case 4 :
                    fprintf(f, "%d\t", x);// fourth, another tab.. fifth is a newline
                    hpos++;
                break;
            }
        }
    }
    printf("\n%d numbers generated", index); // eh, print it out. why not?

    return 0;
}
毫米

do循环中的逻辑是:

  • 选择一个随机数
  • 浏览以前接受的数字列表,看是否存在
    • 如果是这样,请返回并选择另一个随机数
    • 如果没有,请退出此循环

正如评论中所建议的,您的系统可能有,RAND_MAX == 32767因此只有32768可能的随机数。因此,一旦选择了每个循环,则此循环将变为无限循环。

它看起来快要快结束的原因是,do在找到新的数字之间,它将进行多次循环(不显示任何内容)。

如果您将printf("\r%d", index);是内do环路(并且每个迭代变化显示),你应该看到这一点。


为了获得更大范围的随机数,我将使用Mersenne Twister(mt19937)的免费实现,或者在此处查看其他选项。

另外,生成唯一随机数列表的算法效率极低(对现有列表的搜索过多),请参见此处进行改进。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

C ++用随机数填充数组而不重复

如何随机生成AZ以填充数组?

用有距离的随机整数填充数组

为什么用C语言为每个带符号的int类型都必须有一个对应的无符号的int类型?

Javascript,填充数组没有重复的字符串

随机生成没有重复元素的枚举数组(C ++)

填充数组,无论是否有空支票

C:将无符号字符数组转换为带符号的int(反之亦然)

稀疏随机填充数组的Python方法?

填充数组的C ++函数

使用复选框使用 React 填充数组时,数组有重复的记录

用字典填充数组是否会在Python中创建重复的字典?

如何确定数字是否为任何类型的int(核心或numpy,带符号或不带符号)?

Pyspark:填充数组[Int]列为零

用唯一的int填充数组

如何只用 0 到 20 之间的数字填充数组 C 语言

尝试编写程序用C中的随机数填充数组

用C中范围内的随机数填充数组

无法弄清楚用随机数c ++填充数组的函数

检查随机生成的数组中是否存在值

C:生成具有范围内随机数的数组(允许重复)

生成随机数以放置在数组中,如果数字是重复抽奖,则重新滚动。布尔检查是“有时”工作

是否在C中移动带符号的短未定义行为的带符号位?

SetState没有填充数组

用现有对象填充数组

用随机非连续数字填充数组

在libGdx中用随机vector2填充数组

如何用随机数填充数组?

如何用随机值1-110填充数组