Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在集合中使用emplace_hint的用例是什么?_C++_C++11 - Fatal编程技术网

C++ 在集合中使用emplace_hint的用例是什么?

C++ 在集合中使用emplace_hint的用例是什么?,c++,c++11,C++,C++11,在集合中使用emplace_hint的用例是什么?我给出了一个提示(在下面的程序中是s.begin()),但是,emplace_提示似乎没有注意到它。程序- #include <iostream> #include <string> #include <set> using namespace std; void show(set<string>& s) { set<string>::iterator it = s.

在集合中使用emplace_hint的用例是什么?我给出了一个提示(在下面的程序中是s.begin()),但是,emplace_提示似乎没有注意到它。程序-

#include <iostream>
#include <string>
#include <set>

using namespace std;

void show(set<string>& s) {
    set<string>::iterator it = s.begin();

    cout << "<" << *it++;
    for (; it != s.end(); it++)
        cout << ", " << *it;
    cout << ">" << endl;
}


set<string>::iterator myEmplaceHint(set<string>::iterator hint_it, set<string> &s, string e) {

    set<string>::iterator ret_it, tmp_it;

    cout << "hint_it :" << *hint_it << endl;
    ret_it = s.emplace_hint(hint_it, e);
    return ret_it;
}


int main(int argc, char *argv[]){

    set <string> s = { "alpha", "beta", "gamma", "delta" };
    show(s);

    string str("epsilon"), retVal;
    retVal = *myEmplaceHint(s.begin(), s, str);
    cout << "retVal :" << retVal << endl;

    show(s);

    return 0;
}

$ make
g++ -g -Wall -o test test.cpp
$ ./test
<alpha, beta, delta, gamma>
hint_it :alpha
retVal :epsilon
<alpha, beta, delta, epsilon, gamma>
#包括
#包括
#包括
使用名称空间std;
无效显示(设置和设置){
set::iterator it=s.begin();
库特
  • std::set
    始终按比较类型指定的顺序存储项目。这默认为
    std::less
    ,这意味着默认情况下项目将始终为升序。无论您提示什么,集合都保证维护顺序

  • emplace_提示旨在避免在您已经知道项目应插入的位置时再次搜索集合

  • 一个非常简单的例子:

    #include <set>
    #include <cassert>
    
    void ensure_present(std::set<int>& s, int v)
    {
        // finding the upper bound is O(logN)
        auto i = s.upper_bound(v);
        if (i == std::end(s) || *i != v) {
    
            // this would be inefficient since we'd be performing another redundant 
            // O(logN) search for the insertion point
            // s.emplace(v);
    
            // since we already have the position close to were it should go, we
            // can avoid another search
            s.emplace_hint(i, v);
        }
    }
    
    #包括
    #包括
    无效确保存在(标准::设置与s,int v)
    {
    //求上界是O(logN)
    自动i=s.上界(v);
    如果(i==std::end(s)| |*i!=v){
    //这将是低效的,因为我们将执行另一个冗余
    //O(logN)搜索插入点
    //s.emplace(v);
    //既然我们已经有了接近它应该离开的位置,我们
    //可以避免再次搜索
    s、 安放提示(i,v);
    }
    }
    
    良好的暗示有助于提高性能。起初,我在这里写了一条关于性能改进程度的错误评论。但仔细想想,无论如何,复杂性大约为O(n log n),所以我们讨论的是一个常数因子,它取决于数据和实现。请注意,如果您不一定需要按排序顺序重复列出项目,则
    无序集
    为您提供了插入n个项目的O(n)复杂性。@cheers sandhth.-Alf您是否愿意就O(nlogn)复杂性进行说明?我们不是得到了O(1)如果我们提供了正确的提示?由于
    集合
    必须能够生成一个已排序的项目序列,因此它必须使用一个数据结构来对项目进行排序。实际上,这意味着某种平衡树。对于已排序的项目,完美的提示将排除所有现有的树,因为最后添加的节点必须是rightmost,但添加新节点会涉及(我认为这将在大约一半的情况下)树的重新平衡。重新平衡是一个O(logn)操作。重复的(是的,我知道你问过
    set
    ,但实际上它们使用相同的数据结构;set只是一个只有一个键的映射,没有值)您可以在第二点中添加一个注释,大意是“允许实现忽略提示。”同意!在集合s={23,45,21,87,5,33,86,73}上;我尝试了it=s.find(87);s.emplace_hint(it,22);但它仍然在21之后插入。emplace_提示旨在避免在您已经知道项目应插入的位置时再次搜索集合。这是否意味着如果我们提供错误提示,将对性能产生影响?@OnkarNMahajan,这将由实现定义。实际上,您应该预期的最坏影响是提示是ignored,搜索从树的根开始,即返回到O(logN)