C++ 为什么我的二进制搜索比迭代搜索慢得惊人?
我正在编写一个自动完成程序,在给定字典文件和输入文件的情况下,查找一个字母或一组字符的所有可能匹配项。我刚刚完成了一个版本,在迭代搜索的基础上实现了二进制搜索,我认为我可以提高程序的整体性能 事实是,二进制搜索几乎比迭代搜索慢9倍。有什么好处?我认为通过在迭代过程中使用二进制搜索可以提高性能 运行时间(左侧的bin搜索): 这是每个版本的重要部分,可以使用cmake构建和运行完整的代码 二进制搜索函数(在循环给定输入时调用)C++ 为什么我的二进制搜索比迭代搜索慢得惊人?,c++,performance,search,time,binary-search,C++,Performance,Search,Time,Binary Search,我正在编写一个自动完成程序,在给定字典文件和输入文件的情况下,查找一个字母或一组字符的所有可能匹配项。我刚刚完成了一个版本,在迭代搜索的基础上实现了二进制搜索,我认为我可以提高程序的整体性能 事实是,二进制搜索几乎比迭代搜索慢9倍。有什么好处?我认为通过在迭代过程中使用二进制搜索可以提高性能 运行时间(左侧的bin搜索): 这是每个版本的重要部分,可以使用cmake构建和运行完整的代码 二进制搜索函数(在循环给定输入时调用) 而不是在向量的中间删除元素(这相当昂贵),然后开始搜索,只比较找到
<>而不是在向量的中间删除元素(这相当昂贵),然后开始搜索,只比较找到的项之前和之后的元素(因为它们应该都是相邻的)直到找到匹配的所有项。
或者使用,这正是原因。这将是罪魁祸首:
dict.erase(dict.begin() + middle);
您反复从字典中删除条目,以天真地使用二进制搜索查找所有有效前缀。这增加了巨大的复杂性,而且是不必要的
相反,一旦找到匹配项,请后退一步直到找到第一个匹配项,然后向前一步,将所有匹配项添加到队列中。请记住,由于字典已排序,并且仅使用前缀,因此所有有效匹配项都将连续显示。dict.erase操作是dict大小的线性操作:它将整个数组从中间到末端复制到数组的开头。这使得“二进制搜索”算法在dict长度上可能是二次的,O(N^2)昂贵的内存复制操作。通过
一个字母或一组字母
你的意思是它们位于搜索词的开头吗?@SJuan76我编辑了一个示例文件,其中包括图片中使用的搜索词,是的,字母是单词的开头。删除在向量中插入一个项目
是昂贵。不要使用substr
而是尝试使用它们是否给出完全相同的结果?您是否计算了每个循环中执行的操作数并进行了比较?
for(int k = 0; k < input.size(); ++k) {
int len = (input.at(k)).length();
// truth false variable to end out while loop
bool found = false;
// create an iterator pointing to the first element of the dictionary
vecIter i = dictionary.begin();
// this while loop is not complete, a condition needs to be made
while(!found && i != dictionary.end()) {
// take a substring the dictionary word(the length is dependent on
// the input value) and compare
if( (*i).substr(0,len) == input.at(k) ) {
// so a word is found! push onto the queue
matchingCase.push(*i);
}
// move iterator to next element of data
++i;
}
}
z
be
int
nor
tes
terr
on
dict.erase(dict.begin() + middle);