1

我有一个用 c 编写的模拟程序,我需要创建随机数并将它们写入 txt 文件。程序仅停止 - 当再次生成已经生成的随机数或 - 生成 10 亿个随机数时(不重复)

我的问题是无法在txt文件中搜索到生成的long int随机数!文本文件格式为:9875 764 19827 2332 ... 任何帮助表示赞赏.. `

FILE * out;

int checkNumber(long int num){
    char line[512];
    long int number;  
    int result=0; 

    if((out = fopen("out.txt","r"))==NULL){
            result= 1;
    }

    char buf[10];
    itoa(num, buf, 10);


    while(fgets(line, 512, out) != NULL)
    {
       if((strstr(line,buf)) != NULL){
              result = 0;
       }
    }
    if(out) {
        fclose(out);
    } 
    return result;  
}


int main(){
    int seed;
    long int nRNs=0;
    long int numberGenerated;     
    out = fopen ("out.txt","w");

    nRNs=0;
    seed = 12345;

    srand (seed);  

    fprintf(out,"%d\n",numberGenerated);
    while( nRNs != 1000000000 )
    {
      numberGenerated = rand();
      nRNs++;

      if(checkNumber(numberGenerated)==0){
          fclose(out); break; system("pause"); 
      }
      else{
          fprintf(out,"%d\n",numberGenerated);
      }

    }    

    fclose(out);

}`

4

5 回答 5

1

如果文本文件只包含由空格分隔的随机生成的数字,那么您需要strtok()函数(谷歌其用法)并将其放入@jacekmigacz 提到的二叉树结构中。但在任何情况下,您必须至少搜索整个文件一次。然后ftell()是获取您在文件中搜索的位置的值。当生成另一个号码时,您可以使用它fseek()来获取最新号码。记得逐行获取数据fgets()

照顾内存需求并malloc()明智地使用

于 2012-11-28T10:49:57.297 回答
0

不要打开文件并将其扫描到checkNumber(). 你将永远等待。

相反,使用位集数据结构将生成的数字保存在内存中并引用它。

您的位集需要足够大以指示每个 32 位整数,因此它会消耗2^32 / 8字节(或512MiB)的内存。这可能看起来很多,但它比32-bit * 1,000,000,000( 4GB) 小得多。此外,检查和更新都将在恒定时间内完成。

编辑:维基百科链接并没有太多解释如何编写代码,所以这里有一个粗略的示例:(有更快的编写方法,例如:使用位移而不是除法,但这应该更容易理解。 )

int checkNumberOrUpdate(char *bitSet, long int num){
    char b = 1 << (num % 8);
    char w = num / 8;

    if (bitSet[w] & ~b) {
        return 1;
    }
    bitSet[w] |= b;
    return 0;
}

请注意,bitSet需要calloc()从您的主要功能调整到正确的大小。

于 2012-11-28T11:04:09.570 回答
0

尝试使用(数据结构)。

于 2012-11-28T10:42:27.910 回答
0

这可能有效,或者您可以这样处理:(缓慢但会有效)

  int new_rand = rand();
    static int couter = 0;
    FILE *fptr = fopen("txt","a+");
    int i;
    char c,buf[10];
    while((c=getc(fptr))!=EOF)
    {
     buf[j++]=c;
     if(c == ' ')
       {
        buf[--j]='\0';
        i=atoi(buf);
        if(i == new_rand)
           return;
        j=0;
    }
    if(counter < 1000000)
   {
    fwrite(&new_rand, 4, 1, fptr);
    counter++;
   }
于 2012-11-28T11:00:52.737 回答
0

每次在文本文件中线性搜索将永远花费如此多的数字。您可以将迄今为止生成的每个数字按数据结构排序,以便您可以对重复项进行二进制搜索。不过,这将需要大量 RAM。对于具有 32 位整数的系统上已经有 4GB 的 10 亿个整数,您将需要更多的数据结构开销。我的估计在最坏的情况下大约是 16GB(实际上你会得到 10 亿个唯一整数。)

如果您没有内存怪物机器,则应该将数据结构写入二进制文件并在那里进行二进制搜索。虽然这仍然会很慢。

于 2012-11-28T10:49:13.123 回答