【发布时间】:2015-10-14 08:29:02
【问题描述】:
我有一个dictionary .txt 文件,其中可能包含一千多个单词及其定义。我已经编写了一个程序来从这个文件中获取每一行的第一个单词,并根据用户输入的字符串检查它:
void checkWord(string input)
{
std::ifstream inFile;
inFile.open("Oxford.txt");
if (inFile.is_open())
{
string line; //there is a "using std::string" in another file
while (getline(inFile, line))
{
//read the first word from each line
std::istringstream iss(line);
string word;
iss >> word;
//make sure the strings being compared are the same case
std::transform(word.begin(), word.end(), word.begin(), ::tolower);
std::transform(input.begin(), input.end(), input.begin(), ::tolower);
if (word == input)
{
//Do a thing with word
}
}
inFile.close();
return "End of file";
}
else
{
return "Unable to open file";
}
}
但如果我检查的不仅仅是一个句子,处理时间就会变得很明显。我想了一些方法来缩短这段时间:
- 为字母表中的每个字母制作一个 .txt 文件(很容易做到,但从长远来看并不是真正的解决方案)
- 使用 unordered_set 比较字符串(如在 this 问题中)唯一的问题可能是从文本文件中初始创建这些映射
- 使用其他数据结构来比较字符串? (如 std::map)
鉴于数据已经“排序”,我应该采用哪种数据结构或方法来(如果可能)降低时间复杂度?另外,我用来比较字符串的函数有什么问题吗? (例如,string::compare() 会比“==”更快吗?)
【问题讨论】:
-
std::ifstream速度很慢,你可以考虑换一个。 -
搜索 1000 个单词真的需要那么长时间吗?一些真正简单的改进是在读取文件之前将其小写,并在函数开头仅将输入单词小写一次。并且如果多次搜索,将文件内容加载到内存中并搜索加载的列表,而不是多次读取文件。
-
@MatsPetersson:对我来说似乎是一个答案!!
-
我认为没有必要在每次迭代时将
input转换为小写。可能不会带来任何改进,因为一个好的编译器可能无论如何都会优化这部分,但它只会使代码看起来更好。另外,我相信is >> word与字符串标记化方法相比可能是一项相当昂贵的操作(请参阅cplusplus.com/reference/cstring/strtok 或stackoverflow.com/questions/53849/…)。更熟悉 C++ 内部的人可能想对此发表评论。 -
谢谢大家!