聚合 std::multimap 中相同键的值并存储在 std::map 中
Aggregate values of same key in std::multimap and store in std::map
我本质上是想通过键对multimap的元素进行分组,并获得新的数据结构作为一个map。
多图:
std::multimap<std::string,std::vector<int>> multiMap;
VecA VecB
ABC 10 30
ABC 10 30
DEF 20 20
所需的输出:
std::map<std::string,std::vector<int>> map;
VecA VecB
ABC 20 60
DEF 20 20
以下代码适用于 std::multimap<std::string,int>
std::vector<std::string> a = {ABC,ABC,DEF,GHI};
std::vector<int> b = {10,20,30,40};
std::multimap<std::string,int> multiMap;
for (int i = 0; i < a.size(); i++)
{
multiMap.insert(std::pair<std::string,int >(a[i], b[i]));
}
std::map<std::string,int> map;
std::for_each
(
multiMap.begin(),
multiMap.end(),
[&map] (auto const & i)
{
map[i.first] += i.second;
}
);
我无法更改上述块第 19 行的代码(即在 lambda 函数中)以在 std::multimap<std::string,std::vector<int>>
的情况下扩展到 std::map<std::string,std::vector<int>>
如果你想使用算术运算符
使用valarray
演示:https://wandbox.org/permlink/SAnHNKNZ0UufqZsN
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <valarray>
#include <numeric>
int main()
{
using key_type = std::valarray<int>;
key_type b = {10,20,30,40};
auto containerToStr = [](const auto& cont)
{
return std::accumulate(std::begin(cont), std::end(cont), std::string{}, [](const auto& str, const auto& val){
return str + " " + std::to_string(val);
});
};
std::multimap<std::string,key_type> multiMap;
std::vector<std::string> a = {"ABC","ABC","DEF","GHI"};
for (size_t i = 0; i < a.size(); i++)
{
multiMap.insert(std::pair<std::string,key_type >(a[i], b));
}
std::cout << "Before sum" << std::endl;
for (const auto& p : multiMap)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
std::cout << std::endl;
std::map<std::string,key_type> map;
std::for_each( multiMap.begin(), multiMap.end(), [&map] (auto const & i)
{
// map[i.first] += i.second; // caution map[i.first] create an empty key_type
if ( map.count(i.first) > 0)
{
map.at(i.first) += i.second;
}
else
{
map.insert({i.first, i.second});
}
}
);
std::cout << "After sum" << std::endl;
for (const auto& p : map)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
}
如果你想使用std::vector
定义求和函数。
演示:https://wandbox.org/permlink/FteFkLfwQh0P4wzp
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <numeric>
int main()
{
using key_type = std::vector<int>;
key_type b = {10,20,30,40};
auto containerToStr = [](const auto& cont)
{
return std::accumulate(std::begin(cont), std::end(cont), std::string{}, [](const auto& str, const auto& val){
return str + " " + std::to_string(val);
});
};
std::multimap<std::string,key_type> multiMap;
std::vector<std::string> a = {"ABC","ABC","DEF","GHI"};
for (size_t i = 0; i < a.size(); i++)
{
multiMap.insert(std::pair<std::string,key_type >(a[i], b));
}
std::cout << "Before sum" << std::endl;
for (const auto& p : multiMap)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
std::cout << std::endl;
std::map<std::string,key_type> map;
// Warning : naive function, to rework
auto your_sum = [](const auto& cont1, const auto& cont2)
{
key_type result;
const auto smaller = std::min(cont1.size(), cont2.size());
for ( size_t i = 0 ; i < smaller; i++)
{
result.push_back(cont1[i]+cont2[i]);
}
return result;
};
std::for_each( multiMap.begin(), multiMap.end(), [&map,&your_sum] (auto const & i)
{
// map[i.first] += i.second; // caution map[i.first] create an empty key_type
if ( map.count(i.first) > 0)
{
map.at(i.first) = your_sum(i.second, map.at(i.first));
}
else
{
map.insert({i.first, i.second});
}
}
);
std::cout << "After sum" << std::endl;
for (const auto& p : map)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
}
我本质上是想通过键对multimap的元素进行分组,并获得新的数据结构作为一个map。
多图:
std::multimap<std::string,std::vector<int>> multiMap;
VecA VecB
ABC 10 30
ABC 10 30
DEF 20 20
所需的输出:
std::map<std::string,std::vector<int>> map;
VecA VecB
ABC 20 60
DEF 20 20
以下代码适用于 std::multimap<std::string,int>
std::vector<std::string> a = {ABC,ABC,DEF,GHI};
std::vector<int> b = {10,20,30,40};
std::multimap<std::string,int> multiMap;
for (int i = 0; i < a.size(); i++)
{
multiMap.insert(std::pair<std::string,int >(a[i], b[i]));
}
std::map<std::string,int> map;
std::for_each
(
multiMap.begin(),
multiMap.end(),
[&map] (auto const & i)
{
map[i.first] += i.second;
}
);
我无法更改上述块第 19 行的代码(即在 lambda 函数中)以在 std::multimap<std::string,std::vector<int>>
的情况下扩展到 std::map<std::string,std::vector<int>>
如果你想使用算术运算符
使用valarray
演示:https://wandbox.org/permlink/SAnHNKNZ0UufqZsN
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <valarray>
#include <numeric>
int main()
{
using key_type = std::valarray<int>;
key_type b = {10,20,30,40};
auto containerToStr = [](const auto& cont)
{
return std::accumulate(std::begin(cont), std::end(cont), std::string{}, [](const auto& str, const auto& val){
return str + " " + std::to_string(val);
});
};
std::multimap<std::string,key_type> multiMap;
std::vector<std::string> a = {"ABC","ABC","DEF","GHI"};
for (size_t i = 0; i < a.size(); i++)
{
multiMap.insert(std::pair<std::string,key_type >(a[i], b));
}
std::cout << "Before sum" << std::endl;
for (const auto& p : multiMap)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
std::cout << std::endl;
std::map<std::string,key_type> map;
std::for_each( multiMap.begin(), multiMap.end(), [&map] (auto const & i)
{
// map[i.first] += i.second; // caution map[i.first] create an empty key_type
if ( map.count(i.first) > 0)
{
map.at(i.first) += i.second;
}
else
{
map.insert({i.first, i.second});
}
}
);
std::cout << "After sum" << std::endl;
for (const auto& p : map)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
}
如果你想使用std::vector
定义求和函数。
演示:https://wandbox.org/permlink/FteFkLfwQh0P4wzp
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <numeric>
int main()
{
using key_type = std::vector<int>;
key_type b = {10,20,30,40};
auto containerToStr = [](const auto& cont)
{
return std::accumulate(std::begin(cont), std::end(cont), std::string{}, [](const auto& str, const auto& val){
return str + " " + std::to_string(val);
});
};
std::multimap<std::string,key_type> multiMap;
std::vector<std::string> a = {"ABC","ABC","DEF","GHI"};
for (size_t i = 0; i < a.size(); i++)
{
multiMap.insert(std::pair<std::string,key_type >(a[i], b));
}
std::cout << "Before sum" << std::endl;
for (const auto& p : multiMap)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
std::cout << std::endl;
std::map<std::string,key_type> map;
// Warning : naive function, to rework
auto your_sum = [](const auto& cont1, const auto& cont2)
{
key_type result;
const auto smaller = std::min(cont1.size(), cont2.size());
for ( size_t i = 0 ; i < smaller; i++)
{
result.push_back(cont1[i]+cont2[i]);
}
return result;
};
std::for_each( multiMap.begin(), multiMap.end(), [&map,&your_sum] (auto const & i)
{
// map[i.first] += i.second; // caution map[i.first] create an empty key_type
if ( map.count(i.first) > 0)
{
map.at(i.first) = your_sum(i.second, map.at(i.first));
}
else
{
map.insert({i.first, i.second});
}
}
);
std::cout << "After sum" << std::endl;
for (const auto& p : map)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
}