从c中的文本文件中搜索整数

时间:2012-11-28 10:35:59

标签: c search full-text-search type-conversion readfile

我有一个用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);

}`

5 个答案:

答案 0 :(得分:1)

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

注意内存要求,明智地使用malloc()

答案 1 :(得分:0)

尝试使用tree(数据结构)。

答案 2 :(得分:0)

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

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

答案 3 :(得分: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++;
   }

答案 4 :(得分:0)

请勿打开文件并将其扫描到checkNumber()。你会永远等待。

相反,请使用bit set数据结构将生成的数字保存在内存中,并参考该数据。

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

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

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() d来自主要功能的正确尺寸。