我面临以下任务: 将unsigned int的三元组映射到一个值,该值为零或正(double);并且能够给定三元组获得双倍或者说它实际上为零;
我有以下简化: 第一个(让我们称之为I)和第二个(让我们称之为J)整数在已知范围内(从零到IMAX和JMAX)。 对于第三个指数(K),我知道三元组的估计(第三个指数是分散的),比如ESTIMATE; 在计算期间,三胞胎增长的数量,更准确地说,对于给定的I和K,第三指数的数量可以增加。
到目前为止,我看到了以下解决方案:
保持地图矢量的矢量:
vector< vector < map <unsinged int, unsigned int>>> tri_map_;
//^I ^J ^K ^index
如果'index'不为零,则从补充向量中获取值:
vector< double> values;
values[index];
整个事情要初始化为:
tri_map_.resize(IMAX);
for (int i=0;i<IMAX;++i) tri_map_[i].resize(JMAX);
您如何看待该解决方案?有没有更好的方法呢?
我不喜欢的是,似乎我不能做“保留”这样的事情 地图。有没有办法尝试分配足够的内存(因为我对第三个索引有估计)并检查是否有足够的内存?除此之外,我对此感到满意。
EDIT1: IMAX~hundrets JMAX~10 ^ 5
EDIT2:
试图纳入sehe的解决方案,但是
unordered_set和pair;
那么,这就是我遇到问题的地方specialization of ‘template<class _Tp> struct std::tr1::hash’ in different namespace
:
...
EDIT3:以下作品,将调查其速度。
感谢大家的建议和意见!
#include <tr1/functional>
#include <vector>
#include <map>
#include <tr1/unordered_set>
#include <list>
#include <set>
#include <tr1/array>
#include <iostream>
struct pair_int {
unsigned int first;
unsigned int second;
bool operator< (pair_int const& o) const {
if ( first < o.first )
return true;
if ( first > o.first )
return false;
return second < o.second;
}
bool operator==(pair_int const& o) const {
return ( (first==o.first)&&(second==o.second) );
}
};
namespace std {
namespace tr1 {
template<> struct hash<pair_int> {
unsigned int operator()(pair_int const& key) const {
return ~key.first + 17u*key.second;
}
};
}
}
class pair_storage {
public:
pair_storage() {};
~pair_storage();
....
private:
pair_int pair_ij_;
std::map<pair_int,double>::iterator pairMapIterator_;
std::vector< std::map<pair_int,double> > pairMapVector_;
std::vector< std::tr1::unordered_set< pair_int > > pairMapVectorZero_;
};
无法使用-std=c++0x
编译它因为我在大代码的某些部分遇到了一些问题......
答案 0 :(得分:3)
struct Triple
{
unsigned int A;
unsigned int B;
unsigned int C;
};
map<Triple, double> mapping;
答案 1 :(得分:3)
在我看来你正在寻找
下面是一个使用std :: unordered_multimap的简单示例(需要为您的密钥类型专门化std::hash<>
,因此编写它的方式稍微复杂一点):
#include <tuple>
#include <unordered_map>
#include <cassert>
#include <iostream>
struct triplet
{
unsigned a,b,c;
bool operator< (triplet const& o) const { return std::tie(a,b,c) < std::tie(o.a,o.b,o.c); }
bool operator==(triplet const& o) const { return std::tie(a,b,c) ==std::tie(o.a,o.b,o.c); }
};
namespace std {
template<> struct hash<triplet> {
unsigned int operator()(triplet const& key) const {
return ~key.a + 17u*key.b + 17u*key.c; // totally made that up, could be better, I suppose
}
};
}
static std::ostream& operator<<(std::ostream& os, triplet const& key) {
return os << '[' << key.a << ',' << key.b << ',' << key.c << ']';
}
int main()
{
std::unordered_multimap<triplet, double> map;
// insert items dynamically
map.insert({ triplet{ /*I*/ 1, /*J*/ 2, /*K*/ 3 }, 0.1 } );
map.insert({ triplet{ /*I*/ 4, /*J*/ 5, /*K*/ 6 }, 0.2 } );
map.insert({ triplet{ /*I*/ 7, /*J*/ 8, /*K*/ 9 }, 0.3 } );
map.insert({ triplet{ /*I*/ 1, /*J*/ 2, /*K*/ 0 }, 0.4 } ); // duplicate (I,J) ok
map.insert({ triplet{ /*I*/ 1, /*J*/ 2, /*K*/ 0 }, 0.5 } );
assert(0 == map.count(triplet {1,5,6}));
assert(1 == map.count(triplet {4,5,6}));
auto range = map.equal_range(triplet { 1,2,0 });
for (auto it=range.first; it!=range.second; ++it)
std::cout << it->first << ": " << it->second << "\n";
}
输出(如 http://ideone.com/pm8Oz 所示):
[1,2,0]: 0.4
[1,2,0]: 0.5
答案 2 :(得分:1)
关于“这是最优/最有效的方式吗?”这个问题:
尝试使用hash_map
或unordered_map
;可能比map
更快(或者可能不是,取决于您的使用案例)。
关于“有没有办法试图分配足够的内存......?”的问题:
您可以使用unordered_map::max_load_factor
来调整内存/性能权衡;这就像预分配一样。
哦,您还可以使用unordered_set
来存储映射到零的元素。这可能会降低内存消耗,而无需降低性能。