关于任意结构的set_union - 哪里出错了?

时间:2011-06-09 19:43:08

标签: c++ algorithm struct

这是我之前的post的延续,它告诉我该做些什么,但实施它不起作用:S。我想要的只是C ++算法类中的set_union(以及其他设置操作)来处理我的结构。这是我到目前为止所拥有的。

我的结构:

struct player {
    int lbl;
    int lbl1;

    bool operator<(const player &t) const {
        return (lbl < t.lbl && lbl1 < t.lbl);
    }
};

定义&lt;我的结构上的运算符,即如果一个玩家的两个标签(整数)都小于其他玩家的标签,则该玩家比另一个玩家“小”。

然后执行set_union我这样做:

    player p1;
    p1.lbl = 1;
    p1.lbl1 = 3;

    player p2;
    p2.lbl = 3;
    p2.lbl1 = 5;

    player p3;
    p3.lbl = 2;
    p3.lbl1 = 8;

    player p4;
    p4.lbl = 1;
    p4.lbl1 = 7;

    vector<player> v1;
    vector<player> v2;
    v1.push_back(p2);
    v1.push_back(p1);
    v2.push_back(p3);
    v2.push_back(p4);

    sort(v1.begin(), v1.end());
    sort(v2.begin(), v2.end());

    vector<player> v;
    set_union(v1.begin(), v1.end(), v2.begin(), v2.end(),
              back_inserter(v));

    for(int i = 0; i < v.size(); i++) {
        cout << v.at(i).lbl << ", " << v.at(i).lbl1 << endl;
    }

打印:

1, 3
3, 5

应该打印时

1, 3
3, 5
2, 8
1, 7

因为它设置了联合。我在某处的结构定义中可能出错了?相同的set_union适用于字符串和整数的向量,所以它可能是我的播放器结构?

谢谢。

其他代码

我的实际结构代码如下(Nawaz建议的修正)。我最初发布了一个简化版本,但我可能需要发布所有内容:

struct player {
    int i;
    int lbl;
    int lbl1;
    argument argu;
    string player_name;

    player(string player_name);

    bool operator<(const player &t) const {
        if ( lbl != t.lbl )
            return lbl < t.lbl;
        return lbl1 < t.lbl1;
    }

};

1 个答案:

答案 0 :(得分:7)

您应该实施Strict weak ordering,因为关联容器,例如std::setstd::multisetstd::mapstd::multimap要求元素的排序必须是Strict Weak Ordering。在您的情况下,set_union根据std::set规则对数据进行操作,这需要严格弱排序,但您的比较函数不会实现它。因此问题!

另请注意cplusplus上the documentation of std::set_union的内容,

  

比较函数对象,如果第一个参数位于其定义的特定严格弱排序中的第二个参数之前,则返回两个与该范围中包含的值相同的值,并且否则就是假的。

所以,你的比较函数应该是这样的:

struct player {
    int lbl;
    int lbl1;

    bool operator<(const player &t) const 
    {
        if ( lbl != t.lbl )
               return lbl < t.lbl;
        return lbl1 < t.lbl1;
    }
};

这将给出正确的输出。请参阅此在线演示:

http://www.ideone.com/d4Kob