在一个成员变量上合并std :: set

时间:2015-11-02 17:03:07

标签: c++ stl

我的要求是,如果价格相同但是隐含的bool不同,则合并两组的数量。

当前输出:

价格:100 IsImplied:0 数量:10

价格:200 IsImplied:0 数量:20

由于价格100和200已经存在于集合中,因此忽略了p3和p4的插入。

期望的输出:

价格:100 IsImplied:0 数量:40(10 + 30)(数量合并为P1,P3具有相同的价格但不同的是隐含值)

价格:200 IsImplied:0 数量:60(20 + 40)(数量合并为P2,P4价格相同,但隐含价值不同)

class PriceLevel
{
public:
    int price;
    int qty;
    bool isImplied;

    PriceLevel(int _price, int _qty, bool _isImplied)
    {
        price = _price;
        qty = _qty;
        isImplied = _isImplied;
    }

    friend bool operator<(const PriceLevel &p, const PriceLevel &q);
};

bool operator<(const PriceLevel &p, const PriceLevel &q)
{
    if(p.price < q.price)
    {
        return true;
    }
    else
    {
        return false;
    }
}

int main()
{
    std::set<PriceLevel> s1;

    PriceLevel p1(100,10, false);
    PriceLevel p2(200,20, false);
    PriceLevel p3(100,30, true);
    PriceLevel p4(200,40, true);

    s1.insert(p1);
    s1.insert(p2);
    s1.insert(p3);
    s1.insert(p4);

    set<PriceLevel>::iterator it = s1.begin();

    for(; it != s1.end(); it++)
    {
        cout << "Price: " << it->price << endl;

        cout << "Qty : " << it->qty << endl;

        cout << "IsImplied: " << it->isImplied << endl;

    }
}

2 个答案:

答案 0 :(得分:2)

如果您还需要保留数量,您的比较功能应该使用该信息。设置比较适用于严格的弱排序。 有两种方法可以实现这一目标。选择最适合您设计的那个。

1.不要保留一套PriceLevel本身,而是将map与密钥保持为价格和价值作为数量。您的更新功能类似于:

void update(map<int, int> &valueMap, const PriceList &val)
{
    valueMap[val.price] += val.qty;    
}

` 2.修改集合中的插入逻辑。更新看起来像:

void update(set<PriceList> &valueMap, PriceList val)
{
    auto iter = valueMap.find(val);
    if (iter != valueMap.end())
    {
        val.qty = iter->qty + val.qty;
        valueMap.erase(iter);
    }
    valueMap.insert(val);
}

显然你的比较功能需要更新以考虑数量。 它应该看起来像

bool comp(const PriceList& val1, const PriceList& val2)
{
    return make_pair(val1.price, val1.qty) < make_pair(val2.price, val2.qty);
}

答案 1 :(得分:0)

你想做类似以下的事情。请注意,我们只进行一次查找。

// attempt to insert
std::pair<bool, std::set<PriceLevel>::iterator> result = s1.insert(p1);
if (result.first)  // insert did not work since element already existed
{
    PriceLevel & temp = *(result.second);
    if (temp.isImplied != p1.isImplied)
    {
        temp.qty += p1.qty;  // sum
    }
    else
    {
        temp.qty = p1.qty;  // overwrite
    }
}
// otherwise p1 didn't exist and was inserted