首先,有一点背景。我是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] 删除。
我来说两句