我有一个包含300万行的字符串结构。我试图对文件进行排序,如:
aaaaa
aaaab
aaacc
等等。
我正在尝试做Bubbleort。我尝试了10行并且它有效,但是当我尝试整个300万行文件时,它花了30多分钟并且仍在处理。我决定尝试快速排序。但是,我遇到了一个问题:
expected 'const char **' but argument is of type 'struct lines *'
我该如何解决这个问题?这就是我在做的事情:
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#include <ctype.h>
void swap_str_ptrs(char const **arg1, char const **arg2)
{
const char *tmp = *arg1;
*arg1 = *arg2;
*arg2 = tmp;
}
void quicksort_strs(char const *args[], unsigned int len)
{
unsigned int i, pvt=0;
if (len <= 1)
return;
// swap a randomly selected value to the last node
swap_str_ptrs(args+((unsigned int)rand() % len), args+len-1);
// reset the pivot index to zero, then scan
for (i=0;i<len-1;++i)
{
if (strcmp(args[i], args[len-1]) < 0)
swap_str_ptrs(args+i, args+pvt++);
}
// move the pivot value into its place
swap_str_ptrs(args+pvt, args+len-1);
// and invoke on the subsequences. does NOT include the pivot-slot
quicksort_strs(args, pvt++);
quicksort_strs(args+pvt, len - pvt);
}
void main()
{
FILE *dnaFile=fopen("hs_alt_HuRef_chr2.fa", "r"); //file im reading
typedef struct lines
{
char lines[100]; //size of each line
} lines;
int i = 0;
char buf[256];
static lines myDNA[3354419]; //creates the 3m spots for all lines
while (fgets (buf, sizeof(buf), dnaFile))
{
if (i > 0)
strcpy(myDNA[i].lines, buf); //inserting each line into the struct array
i++;
}
// this is the bubblesort approach, works, but it takes too lon
/**int a;
int total;
char temp[150];
char report[100][150];
for(a=0; a<3354419; a++)
{
for(total=a+1; total<=3354419; total++)
{
if(strcmp(myDNA[a].lines,myDNA[total].lines)>0)
{
strcpy(temp,myDNA[a].lines);
strcpy(myDNA[a].lines,myDNA[total].lines);
strcpy(myDNA[total].lines,temp);
}
}
}*/
quicksort_strs(myDNA, 3354419); //attempt at quicksort, which crashes
}
使用QSORT
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#include <ctype.h>
int compare_function(const void *a,const void *b) {
return (strcmp((char *)a,(char *)b));
}
void main()
{
FILE *dnaFile=fopen("hs_alt_HuRef_chr2.fa", "r"); //file with 3 million lines
typedef struct lines
{
char lines[100];
} lines;
int i = 0;
char buf[256];
static lines myDNA[3354419]; // array holding the 3 million lines
while (fgets (buf, sizeof(buf), dnaFile))
{
if (i > 0)
strcpy(myDNA[i].lines, buf); //putting each line into array
i++;
}
qsort(myDNA, 1000, 100, compare_function); //qsort works for first 1k lines, after, messed up
int a;
for (a = 0; a < 1000; a++){
printf("%s", myDNA[a].lines); //printing lines
}
}
答案 0 :(得分:0)
我稍微修改了问题代码。根据我的测试,以下代码似乎可以根据需要运行(如问题所述)。
#include <stdio.h> // printf(), fprintf(), fclose(), feof(), fgets(), fopen()
#include <string.h> // memset(), strcmp(), strdup()
#include <stdlib.h> // malloc(), qsort(), free()
#include <errno.h> // errno, ENOMEM, EIO
#define MAX_FILE_LINES 3354419
#define MAX_LINE_SIZE (255+1)
int compare_function(const void *a, const void *b)
{
return(strcmp(*(const char **)a, *(const char **)b));
}
int main(int argC, char *argV[])
{
int rCode = 0;
char *filePath = "hs_alt_HuRef_chr2.fa";
FILE *dnaFile = NULL;
char **myDNA = NULL;
int myDNAcnt = 0;
int index;
/** Allow user to specify the file path on the command-line. **/
if(argC > 1)
filePath=argV[1];
/** Allocate an array (to hold the 3 million lines). **/
errno=0;
myDNA=malloc(MAX_FILE_LINES * sizeof(*myDNA));
if(NULL == myDNA)
{
rCode=errno?errno:ENOMEM;
fprintf(stderr, "malloc() failed. errno:%d\n", errno);
goto CLEANUP;
}
memset(myDNA, 0, MAX_FILE_LINES * sizeof(*myDNA));
/** Open the file. **/
errno=0;
dnaFile=fopen(filePath, "r");
if(NULL == dnaFile)
{
rCode=errno;
fprintf(stderr, "fopen() failed to open \"%s\". errno:%d\n", filePath, errno);
goto CLEANUP;
}
/** Read the file into the array, allocating dynamic memory for each line. **/
for(myDNAcnt=0; myDNAcnt < MAX_FILE_LINES; ++myDNAcnt)
{
char buf[MAX_LINE_SIZE];
char *cp;
if(NULL == fgets(buf, sizeof(buf), dnaFile))
{
if(feof(dnaFile))
break;
rCode=EIO;
fprintf(stderr, "fgets() failed.\n");
goto CLEANUP;
}
cp=strchr(buf, '\n');
if(cp)
*cp='\0';
errno=0;
myDNA[myDNAcnt] = strdup(buf);
if(NULL == myDNA[myDNAcnt])
{
rCode=errno;
fprintf(stderr, "strdup() failed. errno:%d\n", errno);
goto CLEANUP;
}
}
/** Sort the array. **/
qsort(myDNA, myDNAcnt, sizeof(*myDNA), compare_function);
/** Print the resulting sorted array. **/
for(index=0; index < myDNAcnt; index++)
{
printf("%8d: %s\n",index, myDNA[index]); //printing lines
}
CLEANUP:
/** Close the file. **/
if(dnaFile)
fclose(dnaFile);
/** Free the array. **/
if(myDNA)
{
for(index=0; index < myDNAcnt; index++)
{
free(myDNA[index]);
}
free(myDNA);
}
return(rCode);
}