Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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++ 设置insert进行奇怪的比较_C++_Stl_Set_Comparator - Fatal编程技术网

C++ 设置insert进行奇怪的比较

C++ 设置insert进行奇怪的比较,c++,stl,set,comparator,C++,Stl,Set,Comparator,我无法解释std::set在插入新元素时进行的比较次数。以下是一个例子: 对于此代码 struct A { int i = 0; bool operator()(int a, int b) { ++i; return a < b; } }; int main() { A a; set<int, A> s1(a); s1.insert(1); cout <&

我无法解释std::set在插入新元素时进行的比较次数。以下是一个例子:

对于此代码

struct A {
    int i = 0;
    bool operator()(int a, int b)
    {
        ++i;
        return a < b;
    }
};

int main()
{    
    A a;

    set<int, A> s1(a);

    s1.insert(1);    
    cout << s1.key_comp().i << endl;

    s1.insert(2);    
    cout << s1.key_comp().i << endl;
}

为什么插入第二个元素需要3次比较?o_o

这是使用红黑树实现
std::set
的一个副作用,与标准二叉树相比,它最初需要更多的比较。

我不知道具体情况,因为它们取决于
std::set
实现,但是确定两个项的相等性需要两次比较,因为它基于这样一个事实,
not(x
意味着
x==y

根据树的优化方式,您可能需要进行第一次比较以确定它应该向左还是向右,然后进行两次比较以检查它是否相等


本标准没有要求比较次数为O(对数N),其中N是
集合中已存在的项数
。恒定因素是实施质量问题。

乍一看似乎有些奇怪。你使用的C++标准是什么?哪个stl?调试版本和非调试版本之间是否一致?我增加了测试用例以进行更多的比较,它产生了
[0,3,4,4,5,5,6,6,6]
@Angew是的,不幸的是。对于调试和发布@ BaseSeBi的结果,我使用C++ 11,这里是我的编译器的细节:Apple LLVM版本4.2(CLAN-425.0.28)(基于LLVM 3.2Svn)目标:X86Y64-APPL-DARWIN 114.2线程模型:PosiXi也期待两个非相等测试的比较,但是其中一个测试也暗示了元素应该向右还是向左的结果,所以我不明白你关于第三个的观点comparison@IssamT.:这是因为您假设左/右检查的结果被重新用于相等性测试。正如我的第二段所指出的,不一定如此。@matthieum:我明白你的意思了。但我通常认为stl库是以一种非常智能的方式实现的,因此如果实现不重用以前完成的结果,那就很奇怪了comparison@IssamT.:这是一个相当不成熟的优化。当一棵树有N个级别时,最多有N个比较来定位该位置,然后有2个比较用于相等。N+1(优化)和N+2(非优化)之间的差异并不是很大。当我思考它时,它确实是有意义的:记住上次比较的结果会给每个操作增加开销。对于一棵大树,这些可能会超过你所看到的单个额外的比较。最重要的是,你会得到循环复杂度的增加。你能进一步说明为什么红黑树需要更多的前期比较吗。我对这种结构不够熟悉,无法理解为什么它是一种需求。@MatthieuM。这两个额外的比较源于这样一个事实,即红黑树节点总是有两片叶子,因此第一次插入技术上会添加根和两片(null)叶子,当添加第二个元素时,它必须与两片叶子进行比较,因为与第一片叶子进行比较的任何一片叶子都会返回null。至少这是我有根据的猜测,因为我自己并不太熟悉。
0
3