在一次活动中,我们需要按可控的比例来随机发放我们的奖品,假设需要随机的物品id和概率都在给定的Map<String,Double>prizeMap中,请实现如下这个函数:
String getRandomPrize(Map<String,Double>prizeMap){}使得返回的结果为参与者
即将得到的一个随机物品id.
prizeMap中的数据为:
物品id 投放概率1 0.52 0.33 0.14 0.955. 0.05
#include <iostream>
#include <map>
#include <string>
#include <ctime>
using namespace std;
string getRandomPrize(map<string, double> hm)
{
double all = 0.0;
map<double, string> mp;
map<string, double>::iterator it = hm.begin();
while (it != hm.end())
{
all += (*it).second;
mp.insert(pair<double, string>(all, (*it).first));
++it;
}
srand((unsigned)time(NULL));
double total = rand() / double(RAND_MAX) * all;
map<double, string>::iterator mpit = mp.begin();
while (mpit != mp.end())
{
if (total < (*mpit).first)
return (*mpit).second;
++mpit;
}
return "";
}
int main(void)
{
map<string, double> hm;
hm.insert(pair<string, double>("1", 0.5));
hm.insert(pair<string, double>("2", 0.3));
hm.insert(pair<string, double>("3", 0.1));
hm.insert(pair<string, double>("4", 0.95));
hm.insert(pair<string, double>("5", 0.05));
while (1)
cout << getRandomPrize(hm);
return 0;
}
法1:直接从左到右一次相加。每次相加都记录相加后的结果:0.5 0.8 0.9 1.85 1.9,if(产生的随机数<=0.5)则说明选到了物品1,else if(产生的随机数<=0.8)则说明选到了物品2,以此类推。
法2:将0.5 0.3 0.1 0.95 0.05按照比例映射为[0,1]之间的数,再将映射后的五个数从左到右相加。剩余步骤同法1后半部分。
我用的法1
所用数据结构: map和string
#include
#include
#include //map由红黑树实现,其中的关键字有序
using namespace std;
string getRandomPrize(map prizeMap)
{
double sum=0;
map::iterator iter=prizeMap.begin();
map tempMap;
while(iter!=prizeMap.end())
{
sum+=iter->second;
tempMap.insert(pair(iter->first,sum));
++iter;
}
//计时器原理实现种子,若每次调用时都重新设置种子,那多次调用的结果相同
//srand((unsigned)time(NULL));
//产生[a,b]上的随机数 ((double)rand()/RAND_MAX)*(b-a) + a ,其中
//(double)rand()/RAND_MAX)得一个0~1的随机数
double total = (double(rand()) / RAND_MAX) * sum;//0到sum间的浮点数
map::iterator it=tempMap.begin();
while(it!=tempMap.end())
{
if(total<(*it).second)
return (*it).first;
++it;
}
}
int main()
{
map prizeMap = {{"1",0.5},{"2",0.3},{"3",0.1},{"4",0.95},
{"5",0.05}};
int i=5000;
srand((unsigned)time(NULL));//应在这设种子,这样每次调用结果才随机。
while(i--)
cout << getRandomPrize(prizeMap) << endl;
return 0;
}
}我写的我觉得还是有错。。。。