文本文件处理速度

时间:2017-10-25 21:49:50

标签: c algorithm performance text-processing

所以我有一个文本文件,其中包含大约666 000行最多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;
}

问题是此功能的运行时间为600 000行/文件约为14秒。我想这是我用strtok和文件实现从文件的每一行获取元素的方式。你们知道一个更好的方法,可以在不需要量子计算机的情况下将运行时间缩短到1秒以下吗? :D提前谢谢你。

1 个答案:

答案 0 :(得分:0)

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

请注意,除了编译没有错误之外,此功能尚未经过测试。它需要<stdbool.h><stdio.h><stdlib.h><string.h>才能进行编译:

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;
}

我将lookupSize设置为100,因为您的号码似乎在099的范围内。如果你有更大的数字,你需要为你的查找表声明一个数组,其大小等于你正在使用的范围内的最大整数值,这就是为什么我只建议这个方法相对较小范围。

相关问题