以下是我根据用户定义的加权值生成随机数的代码。一切正常,直到我试图使数据类型成为任何类型,例如双,漂浮。我在实践中实施它们的经验很少,只能在教科书上阅读。任何人都可以帮我解决吗?
谢谢,
class WeightedRandom
{
public:
template <class T1,class T2>
void setWeight(T1 i,T2 val)
{
m[i]=val;
total+=val;
}
void generator()
{
int val=rand()%total;
for (auto a:m)
{
if (val<a.second)
{
res[a.first]++;
break;
}
val-=a.second;
}
}
void print()
{
for (auto a:res)
{
cout<<a.first<<" "<<a.second<<endl;
}
}
private:
template <class T1,class T2>
unordered_map<T1,T2> m;
template <class T3,class T4>
unordered_map<T3,T4> res; // object-count
int total=0;
};
int main(int argc, const char * argv[])
{
WeightedRandom WR;
WR.setWeight(1, 5);
WR.setWeight(2, 20);
WR.setWeight(3, 50);
WR.setWeight(4, 20);
WR.setWeight(5, 10);
int n=10000;
for (int i=0;i<n;++i)
{
WR.generator();
}
WR.print();
}
答案 0 :(得分:0)
你只需要对类进行模板化,允许总计为模板类型。
#include<unordered_map>
#include<iostream>
#include<math.h>
using namespace std;
template<typename T1,typename T2>
class WeightedRandom{
public:
void setWeight(T1 i,T2 val)
{
m[i]=val;
total+=val;
}
void generator()
{
T2 val= (T2) fmod(rand(),total);
for (auto a:m)
{
if (val<a.second)
{
res[a.first]++;
break;
}
val-=a.second;
}
}
void print()
{
for (auto a:res)
{
cout<<a.first<<" "<<a.second<<endl;
}
}
private:
unordered_map<T1,T2> m;
unordered_map<T1,T2> res; // object-count
T2 total=0;
};
int main(int argc, const char * argv[])
{
WeightedRandom<int,double> WR;
WR.setWeight(1, 5.01);
WR.setWeight(2, 19.99);
WR.setWeight(3, 50.01);
WR.setWeight(4, 19.99);
WR.setWeight(5, 10.00);
int n=10000;
for (int i=0;i<n;++i)
{
WR.generator();
}
WR.print();
}
fmod取一个double,所以如果它是一个int或一个浮点数,它将被提升为一个double并且结果将被强制转换,或者如果它是一个double,则转换为什么都不做。您可能需要考虑添加一些检查以确保仅使用double / float或char / short / int / long,因为用户可能会使用某些类来进行权重很有道理:
...
class WeightedRandom{
static_assert(!is_same<T,bool>(),"type can't be a bool");
static_assert(is_arithmetic<T>(),"type needs to be an arithmetic");
...