私はデータ マイニング クラスのプロジェクトを持っています。このプロジェクトでは、ファイルのリザーバー サンプリング アルゴリズムをコーディングする必要があります。このプログラムは、数値 k、入力ファイルの名前、および作成する出力ファイルの名前を入力として受け取ります。出力ファイルには、入力からの k 個のランダムな行が含まれている必要があります。いくつか試してみましたが、出力が間違っています。
これは私が使用するコードです:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
int countLines(FILE* file)
{
char ch,lines=0;
while ((ch=fgetc(file)) != EOF)
if (ch=='\n')
lines++;
return(lines);
}
void itemSelection(FILE* fp1, FILE* fp2, int k)
{
int i,j,n,test=0;
char line[256];
char** buffer;
srand((unsigned int) time(NULL));
buffer = (char**)malloc(sizeof(char*));
for(i=0;i<k;i++)
buffer[i] = (char*)malloc(256*sizeof(char));
n = countLines(fp1);
if(k>n)
{
rewind(fp1);
while(fgets(line, 256, fp1)!=NULL)
{
printf("%s test\n",line);
fprintf(fp2,"%s",line);
}
}
else
{
rewind(fp1);
for(i=0;i<k;i++)
{
fgets(line, 256, fp1);
buffer[i]=line;
printf("first k lines:\t%s\n",buffer[i]);
}
for(i=k;i<n;i++)
{
fgets(line,256,fp1);
printf("line is:\t%s.\n", line);
j = rand() % (i+1);
if(j<k)
{
buffer[j]=line;
printf("later parts are:\t%s. J is:%d.\n",buffer[j],j);
}
}
}
for(i=0;i<k;i++)
printf("buffer test:\t%s.\n", buffer[i]);
}
void printFunc(FILE* fp2,int k)
{
char line[256];
int i;
rewind(fp2);
for(i=0;i<k;i++)
{
fgets(line, 256, fp2);
printf("print test is:\t%s.\n",line);
}
}
void main(int args, char** argv)
{
FILE* fp1;
FILE* fp2;
int k;
if(args<4)
{
printf("Expected more arguments!\n");
exit(-1);
}
fp1 = fopen(argv[2],"r");
if(fp1 == NULL)
{
printf("Could not open input file!\n");
perror("Error: ");
exit(-1);
}
fp2 = fopen(argv[3],"w");
if(fp2 == NULL)
{
printf("Could not open output file!\n");
perror("Error: ");
exit(-1);
}
k = atoi(argv[1]);
itemSelection(fp1, fp2, k);
printFunc(fp2,k);
fclose(fp1);
fclose(fp2);
}
このプログラムがやろうとしているのは、ファイルから最初の k 行を読み取り、それを (k,256) サイズの 2 次元文字列配列に格納することです。次に、次の行ごとに乱数 j を生成し、その数が k より小さい場合、buffer[j] をファイルから取得した最新の行に置き換えます。
}
ただし、出力は、入力の最後の文字であるの k 行で構成されています。このように (例: k=5):
}
}
}
}
}
バッファを印刷してその内容を確認すると、正しく表示されます。しかし、ファイルに書き込むと、間違った出力が書き込まれます。
どんな助けでも大歓迎です!前もって感謝します!