C 文本文件处理速度

C 文本文件处理速度,c,algorithm,performance,text-processing,C,Algorithm,Performance,Text Processing,因此,我有一个文本文件,包含大约666000行,每行最多10个数字,用空格隔开。例如: 8 38 62 39 4 50 86 43 53 78 38 22 39 29 78 5 24 13 58 92 ....... 53 78 38 22 39 29 78 5 给定一个n数字序列,我必须验证一行是否具有序列中的所有元素 我试过这样的方法: int check() { int nrelem = 0, nr, line_int[11]; int found_counter = 0

因此,我有一个文本文件,包含大约666000行,每行最多10个数字,用空格隔开。例如:

8 38 62 39 4 50 86 43
53 78 38 22 39 29 78 5
24 13 58 92
.......
53 78 38 22 39 29 78 5
给定一个n数字序列,我必须验证一行是否具有序列中的所有元素

我试过这样的方法:

int check()
{
    int nrelem = 0, nr, line_int[11];
    int found_counter = 0, sw = 0;
    char *p;

    f = fopen("temp.txt", "rt");

    while (!feof(f))
    {
        nrelem = 0; found_counter = 0; sw = 0;

        fgets(line, 256, f);

        p = strtok(line, " ");
        while (p != NULL)
        {
            sscanf(p, "%d", &line_int[nrelem++]);
            p = strtok(NULL, " ");
        }

        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < nrelem; j++)
            {
                if (seq[i] == line_int[j])
                {
                    sw = 1;
                    break;
                }
            }
            if (sw)
                found_counter++;
        }
        if (found_counter == nrelem)
            return 0;
    }
    fclose(f);
    return 1;
}
int-check()
{
int nrelem=0,nr,line_int[11];
int=0,sw=0;
char*p;
f=fopen(“温度txt”、“rt”);
而(!feof(f))
{
nrelem=0;找到的计数器=0;sw=0;
fgets(第256行,f);
p=strtok(第“”行);
while(p!=NULL)
{
sscanf(p,“%d”和line_int[nrelem++]);
p=strtok(空,“”);
}
对于(int i=0;i

问题是此函数的运行时间(60万行/文件)约为14秒。我想这是我用strtok从文件的每一行获取元素的方式,以及用文件实现元素的方式。你们知道一种更好的方法吗,可以将运行时间减少到1秒以下,而不需要量子计算机D提前谢谢。

正如我在评论中建议的那样,在算法中使用哈希映射将降低检查序列中是否有数字的时间复杂度
seq
。我还将函数的签名改为更有意义的签名,并加入了其他评论中的一些建议

请注意,除了编译时没有出现错误外,此函数尚未经过测试。它需要
才能编译:

bool check(char *filename, int *seq, size_t seqSize) {
    size_t lookupSize = 100;
    char lookup[lookupSize];
    FILE *fp;
    char *line = NULL;
    size_t len = 0;
    long int num;
    bool result = true;

    memset(hash, 0, lookupSize);

    for (size_t index = 0; index < seqSize; index++) {
        hash[seq[index]] = 1;
    }

    fp = fopen(filename, "r");

    if (fp != NULL) {
        while (getline(&line, &len, fp) != -1 && result) {
            char *cp = line;
            result = false;

            while (*cp != '\0' && !result) {
                num = strtol(cp, &cp, 10);
                result = num < lookupSize && !lookup[num];
            }
        }

        fclose(fp);
        free(line);
    }

    return result;
}
bool检查(char*filename,int*seq,size\u t seqSize){
大小\u t lookupSize=100;
字符查找[查找大小];
文件*fp;
char*line=NULL;
尺寸长度=0;
长整数;
布尔结果=真;
memset(散列,0,lookupSize);
对于(大小索引=0;索引

我将
lookupSize
设置为
100
,因为您的数字似乎在
0
99
的范围内。如果有较大的数字,则需要为查找表声明一个数组,该数组的大小等于所使用范围内最大整数值的1倍,这就是为什么我只建议在相对较小的范围内使用此方法。

正如我在评论中所建议的,在算法中使用散列映射可以降低检查序列
seq
中是否有数字的时间复杂度。我还将函数的签名改为更有意义的签名,并加入了其他评论中的一些建议

请注意,除了编译时没有出现错误外,此函数尚未经过测试。它需要
才能编译:

bool check(char *filename, int *seq, size_t seqSize) {
    size_t lookupSize = 100;
    char lookup[lookupSize];
    FILE *fp;
    char *line = NULL;
    size_t len = 0;
    long int num;
    bool result = true;

    memset(hash, 0, lookupSize);

    for (size_t index = 0; index < seqSize; index++) {
        hash[seq[index]] = 1;
    }

    fp = fopen(filename, "r");

    if (fp != NULL) {
        while (getline(&line, &len, fp) != -1 && result) {
            char *cp = line;
            result = false;

            while (*cp != '\0' && !result) {
                num = strtol(cp, &cp, 10);
                result = num < lookupSize && !lookup[num];
            }
        }

        fclose(fp);
        free(line);
    }

    return result;
}
bool检查(char*filename,int*seq,size\u t seqSize){
大小\u t lookupSize=100;
字符查找[查找大小];
文件*fp;
char*line=NULL;
尺寸长度=0;
长整数;
布尔结果=真;
memset(散列,0,lookupSize);
对于(大小索引=0;索引

我将
lookupSize
设置为
100
,因为您的数字似乎在
0
99
的范围内。如果有较大的数字,则需要为查找表声明一个数组,该数组的大小等于所使用范围内最大整数值的1倍,这就是为什么我只建议在相对较小的范围内使用此方法。

“我猜”-性能优化应基于测量,而不是假设。对其进行分析,然后进行优化。“已经完成了”,那么分析到底告诉了你什么?瓶颈是什么?如何使用
fread
将整个文件读取到内存,然后在内存中进行文本处理?请注意,最好使用
while(fgets(line,256,f)!=NULL)
控制循环。并将最后读取的换行符添加到
strtok
分隔符中,比如
“\n”
。我们将对此进行查看。但最大的问题是:p=strtok(行“”);而(p!=NULL){sscanf(p,“%d”,&line_int[nrelem++]);p=strtok(NULL,”;}这需要10秒。这里,我尝试将每行字符从字符串转换为整数数组。如何解决这个问题?这是一个大问题:对于整个文本文件,这是否可以减少到1秒以下?“我想”-性能优化应该基于测量,而不是假设。对其进行分析,然后进行优化。“已经完成了”,那么分析到底告诉了你什么?瓶颈是什么?如何使用
fre将整个文件读取到内存中