[英]Merge two std::sets
I need to merge two sets into a resultant set on basis of one member variable qty if the prices are same. 如果价格相同,我需要根据一个成员变量qty将两个集合合并为结果集合。 In the below example my resultant set s3 should contain: 在下面的示例中,我的结果集s3应该包含:
Price : 100 Qty : 40 价格:100数量:40
Price : 200 Qty : 60 价格:200数量:60
Please note qty above is a sum of qty in both the sets respective when the price is same. 请注意,上述数量是当价格相同时两组中的数量之和。
My question is how do I construct the set s3 below: 我的问题是如何构造下面的set s3:
Please guide me with the same. 请同样指导我。
#include <set>
#include <iostream>
using namespace std;
class PriceLevel
{
public:
int price;
int qty;
PriceLevel(int _price, int _qty)
{
price = _price;
qty = _qty;
}
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;
std::set<PriceLevel> s2;
PriceLevel p1(100,10);
PriceLevel p2(200,20);
PriceLevel p3(100,30);
PriceLevel p4(200,40);
s1.insert(p1);
s1.insert(p2);
s2.insert(p3);
s2.insert(p4);
std::set<PriceLevel> s3;
set<PriceLevel>::iterator it = s3.begin();
// How should I Initialize s3
for(; it != s3.end(); it++)
{
cout << "Price: " << it->price << endl;
cout << "Qty : " << it->qty << endl;
}
}
If you are absolutely sure that both source sets contain exactly the same prices, you can use the binary version of std::transform
. 如果您完全确定两个源集包含的价格完全相同,则可以使用std::transform
的二进制版本。
If they might contain unequal data, you'll have to do it manually, like this: 如果它们可能包含不相等的数据,则必须手动进行操作,如下所示:
std::set<PriceLevel> s3;
// How should I Initialize s3
std::set<PriceLevel>::iterator
first1 = s1.begin(),
last1 = s1.end(),
first2 = s2.begin(),
last2 = s2.end();
while (first1 != last1 && first2 != last2) {
if (first1->price < first2->price) {
s3.insert(*first1++);
}
else if (first1->price > first2->price) {
s3.insert(*first2++);
}
else {
s3.insert(PriceLevel(first1->price, first1->qty + first2->qty));
++first1;
++first2;
}
}
while (first1 != last1) {
s3.insert(*first1++);
}
while (first2 != last2) {
s3.insert(*first2++);
}
This is best put in an extra function. 最好将它放在一个附加功能中。
If you only need those prices in the result set which existed in both source sets, it is a bit simpler: 如果您只需要两个源集中都存在的结果集中的价格,则要简单一些:
while (first1 != last1 && first2 != last2) {
if (first1->price < first2->price) {
++first1;
}
else if (first1->price > first2->price) {
++first2;
}
else {
s3.insert(PriceLevel(first1->price, first1->qty + first2->qty));
++first1;
++first2;
}
}
set
is not an appropriate data structure for your application here. set
不是适合您的应用程序的数据结构。 Consider using a map<int, int>
instead: 考虑使用map<int, int>
代替:
map<int, int> p1, p2, p3; // map price -> quantity
p1[100] = 10;
p1[200] = 20;
p2[100] = 30;
p2[200] = 40;
p3 = p1;
for(auto &i : p2) {
p3[i.first] += i.second;
}
// Now p3[100]=40 and p3[200]=60.
You can also use a set
kind of like a map
using set::find
: 您也可以使用set
有点像一个map
使用set::find
:
s3 = s1;
for(auto &i : s2) {
auto it = s3.find(i);
if(it == s3.end()) {
s3.insert(i);
} else {
it->qty += i.qty;
}
}
For this to work, you will have to declare qty
as a mutable int
, so that it can be modified even if the PriceLevel
struct is const
(since elements of a set
are const
). 为此,必须将qty
声明为mutable int
,以便即使PriceLevel
结构为const
(因为set
元素为const
),也可以对其进行修改。
If you can't make the variable mutable
, then you can try removing the existing set element and then adding a new, merged element. 如果不能使变量mutable
,则可以尝试删除现有的set元素,然后添加一个新的合并元素。
You are essentially trying to use a set as a map AND merge values with equal keys. 本质上,您试图将集合用作映射并使用相等的键合并值。 You will need to roll your own result (not to mention that it really isn't advisable...). 您需要滚动自己的结果(更不用说它确实不建议...)。 Here is something to get you started. 这是一些让您入门的东西。
#include <iostream>
#include <set>
using namespace std;
class PriceLevel
{
public:
int price;
int qty;
PriceLevel() {
price = 0;
qty = 0;
}
PriceLevel(int _price, int _qty)
{
price = _price;
qty = _qty;
}
friend bool operator<(const PriceLevel &p, const PriceLevel &q);
//Compares two PriceLevel objects and merges their values if their keys are the same.
//Return value is a std::pair that
//denotes if the compare was successful and the result is meaningful.
static std::pair<bool, PriceLevel> merge_equal(const PriceLevel& p, const PriceLevel& q) {
std::pair<bool, PriceLevel> result;
result.first = false;
if(p.price == q.price) {
result.first = true;
result.second.price = p.price;
result.second.qty = p.qty + q.qty;
}
return result;
}
};
bool operator<(const PriceLevel &p, const PriceLevel &q)
{
if(p.price < q.price)
{
return true;
}
else
{
return false;
}
}
int main()
{
std::set<PriceLevel> s1;
std::set<PriceLevel> s2;
PriceLevel p1(100,10);
PriceLevel p2(200,20);
PriceLevel p3(100,30);
PriceLevel p4(200,40);
s1.insert(p1);
s1.insert(p2);
s2.insert(p3);
s2.insert(p4);
std::set<PriceLevel> s3;
//Just in case...the world may explode otherwise.
if(s1.size() == s2.size()) {
for(const auto& pl1 : s1) {
for(const auto& pl2 : s2) {
//Only insert valid values.
auto r = PriceLevel::merge_equal(pl1, pl2);
if(r.first) s3.insert(r.second);
}
}
for(auto it = s3.begin(); it != s3.end(); it++) {
cout << "Price: " << it->price << endl;
cout << "Qty : " << it->qty << endl;
}
}
}
You can merge two sets with just two lines 您只需两行就可以合并两个集合
#include <set>
template <typename _Ty>
std::set<_Ty> merge(const std::set<_Ty> &x, const std::set<_Ty> &y) const
{
std::set<_Ty> merged = x; //initial merged set from x
merged.insert(y.begin(), y.end()); //add contents of y to merged
return move(merged);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.