在C程序中,我需要在普通文件中搜索确切的字符串(我使用Linux)。我该怎么做才能搜索?
我的第一个假设包括将文件的每一行移动到RAM(通过 fgets()),并在每次移动后检查该行是否是正确的字符串。如果不是,循环将重新调用 fgets()并检查字符串直到EOF。
但是,拥有1.5亿行的文件会发生什么?发现这种顺序搜索似乎根本无效。
但是,我正在考虑使用插入排序进行二元搜索,以便对我的程序添加到文件中的行进行排序(它每隔3秒左右添加一行,在检查到该行之后立即添加一行) t出现在字符串文件中)。但后来我放弃了,因为我首先需要将线路移动到RAM,使用的时间与用于顺序搜索的时间相同。因此我选择了顺序搜索。
这个假设是对的吗?或者,还有更好的方法?我真的希望如此。
答案 0 :(得分:2)
您可以使用mmap
将整个文件映射到内存中,然后进行strnstr
搜索:
#include <sys/mman.h>
const char *fileName = "~/test.txt";
long fileLength;
// open file and get it's length
FILE *fptr = fopen(fileName, "r");
if (fptr == NULL || ferror(fptr))
{
perror("could not open file");
fclose(fptr);
return 0;
}
fseek(fptr, 0, SEEK_END);
fileLength = ftell(fptr);
// return to the start of the file
fseek(fptr, 0, SEEK_SET);
// map the file
char *fileData = mmap(NULL, fileLength, PROT_READ, MAP_FILE | MAP_SHARED, fileno(fptr), 0);
if (fileData == MAP_FAILED)
perror("could not map file");
// scan the file
char stringToSearchFor[] = "this is my string!";
if (strnstr(fileData, stringToSearchFor, fileLength) != NULL)
{
printf("file contains the string!");
}
else {
printf("file doesn't contain the string");
}
// clean up our code
munmap(fileData, fileLength);
fclose(fptr);
答案 1 :(得分:0)
答案 2 :(得分:0)
您能提供更多信息吗? 普通文件是什么意思? 您需要进行的文件最大大小是什么?
如果它是大文件而您需要执行快速搜索,请按照下一个算法原型进行操作:
您的搜索算法将取决于您将使用的索引类型。(它可能是树木,二叉树等)
有关更多信息,您需要了解索引,搜索索引,存在的开源搜索系统,例如:apache lucene和sphinx。
UPD:这将是有用的链接: Implementing a index for text file content
https://superuser.com/questions/233665/efficient-way-to-index-text-files
答案 3 :(得分:0)
尝试在大数据上匹配字符串时,可以创建快捷方式过滤器来固定该过程。 firefox扩展AdBlock Plus实际上使用此技术来检查传入的页面请求,并将其与大量过滤器匹配。然后它会阻止匹配的过滤器(广告)。但我离题了。
当你将一个字符串与n个文字匹配时,在算法上它需要best case scenario中的O(n)时间 减少匹配字符串的时间消耗的技巧是减小 n 的大小。 快捷方式过滤器的概念是您创建包含在相关字符串中的短模式。这样,您花费较少的时间来检查每个字符串的正确性。如果过滤器匹配字符串,则检查完整字符串。
基本上可以说我有3个字符串:
1)ABCDABCD 2)DCBABCDA 3)ABDEFGHI
假设我有一个模式“ABC”。迭代时,第1和第2个字符串将返回匹配。第三个字符串被拒绝。然后,只检查那些匹配正确字符串模式的字符串。 另一方面。模式“EFG”拒绝1和2(在更短的时间内)并匹配3.
通过使用哈希表可以进一步改善子串的匹配。 在这里,您可以修复子字符串的大小,如上所述。 然后,对于每个字符串,您计算长度为3的所有子字符串的哈希值。这样,您可以快速确定(在O(1)时间内)哪些模式与字符串匹配。