2017-08-04 41 views
0

我是将一个矢量元素分组到地图中,是否有更高效或更优雅的方式来执行它,而不是我目前的应用程序? - 我认为它在代码方面很麻烦,而且在性能方面也不是最佳的。我如何优雅而高效地将矢量的元素分组到地图中?

我是从C#,其中I通常会使用如这样的解决这样的情况来:

var groupedObservations = observations.GroupBy(o => o.x, o => o.y,o => o.z); 

在我目前C++,我第一排序含的所有元素,然后使用if语句我确定向量当一个新的组织开始并将所有后续的“平等”要素推入该组。

我现在的代码如下;

struct Observation { int id; double x,y,z; } 
vector<std::shared_ptr<Observation>> observations; 

..code that fills observations from csv is omitted .. 

map<int,vector<shared_ptr<Observation>>> groupedObservations; 


std::sort(observations.begin(), observations.end(), sorting_functor()); 

int groupId = 0; 
double x =0 ,y =0 ,z = 0; 
for(shared_ptr<Observation> &observation: observations) 
{ 
    if(!(x == record->x && y== observation->y && z == observation->z)) 
    { 
     groupId++; //coordinates different; new group. 
     x = observation->x; 
     y = observation->y; 
     z = observation->z; 

    } 
    groupedObservations[groupId].push_back(observation); 
} 

为了完整性,分拣函子如下:

struct sorting_functor 
{ 
    bool operator()(const shared_ptr<Observation> &a, shared_ptr<Observation> &b) const 
    { 
     return (a->x < b->x) && (a->y < b->y) && (a->z < b->z); 
    } 
}; 
+0

也许我可以制作一张不是基于3双打的地图,而是基于我使用的三个双打的'独特'值。 - 也许是一个按位或?不过,我不知道该怎么做。 – Joeppie

+0

@ O'Neil一个向量,谢谢你指出,纠正了它的声明。 – Joeppie

+1

https://www.youtube.com/watch?v=mFUXNMfaciE – slf

回答

1

一个工作示例:

#include <unordered_set> 
#include <iostream> 
#include <boost/functional/hash.hpp> 
#include <tuple> 

struct Observation { int id; double x,y,z; }; 
namespace std 
{ 
template<typename... T> 
struct hash<tuple<T...>> 
{ 
    size_t operator()(tuple<T...> const& arg) const noexcept { 
     return boost::hash_value(arg); 
    } 
}; 

template<> 
struct hash<Observation> 
{ 
    size_t operator()(const Observation& o) const 
    { 
     tuple<double, double, double> t{o.x, o.y, o.z}; 
     return hash<tuple<double, double, double> >()(t); 
    } 
}; 

} 

std::ostream& operator<<(std::ostream& os, Observation o) { 
    return os<<o.id<<' '<<o.x<<' '<<o.y<<' '<<o.z; 
} 
bool operator==(const Observation& a, const Observation& b) { 
    return a.x==b.x && a.y==b.y && a.z==b.z; 
} 

int main(int argc, char *argv[]) 
{ 
    std::vector<Observation> a = { 
     {1, 1.0,1.0,1.1}, 
     {2, 1.0,1.0,1.1}, 
     {3, 3.0,3.0,3.3}, 
     {4, 1.0,1.0,1.1}, 
     {5, 3.0,3.0,3.3}, 
     {6, 5.0,5.0,5.5}, 
     {7, 5.0,5.0,5.5}, 
     {8, 5.0,5.0,5.5}, 
     {9, 2.0,2.0,2.2}, 
     {10,2.0,2.0,2.2}, 
     {11,5.0,5.0,5.5}, 
     {12,4.0,4.0,4.4}, 
    }; 
    std::unordered_multiset<Observation> words; 
    words.insert(a.begin(), a.end()); 
    for(auto it = words.begin(); it != words.end();) 
    { 
     auto cnt = words.count(*it); 
     for(auto i=0;i<cnt;i++) 
      std::cout << *it++ << '\n'; 
     std::cout<<'\n'; 
    } 
    return 0; 
} 

其给出

10 2 2 2.2 
9 2 2 2.2 

11 5 5 5.5 
8 5 5 5.5 
7 5 5 5.5 
6 5 5 5.5 

5 3 3 3.3 
3 3 3 3.3 

12 4 4 4.4 

4 1 1 1.1 
2 1 1 1.1 
1 1 1 1.1 

也可以排序的矢量如前所述,然后使用https://github.com/Dobiasd/FunctionalPlus/blob/master/include/fplus/split.hpp,它给你非常干净的代码风格。

auto vector_of_vector = fplus::group(your_vector); 
相关问题