所以我有一个文本文件,其中包含大约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提前谢谢你。
答案 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
,因为您的号码似乎在0
到99
的范围内。如果你有更大的数字,你需要为你的查找表声明一个数组,其大小等于你正在使用的范围内的最大整数值,这就是为什么我只建议这个方法相对较小范围。