首页 > 试题广场 >

请实现如下这个函数: String getRandomPri

[问答题]
在一次活动中,我们需要按可控的比例来随机发放我们的奖品,假设需要随机的物品id和概率都在给定的Map<String,Double>prizeMap中,请实现如下这个函数: String getRandomPrize(Map<String,Double>prizeMap){}使得返回的结果为参与者 即将得到的一个随机物品id.
prizeMap中的数据为:
物品id     投放概率
1            0.5
2            0.3
3            0.1
4            0.95
5.           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;
}

发表于 2016-01-29 20:20:15 回复(0)

详细分析请见我的博客:http://blog.csdn.net/BillCYJ/article/details/79018918

分析

法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;
}
编辑于 2018-01-10 02:16:12 回复(1)
#include <iostream>
//
#include <map>
//#include <stdio.h>
#include <string>
//
#include <vector>
using namespace std;


string getRandomPrize(map<string, double> prizeMap)
{
map<string, double>::iterator it = prizeMap.begin();
int i = rand()%5 + 1;
double ss = 0.0;
//i = 1;
char a[6];
string str = _itoa(i, a, 6);
it = prizeMap.find(str);
//
char buff[20];
sprintf_s(buff, "%0.2f", it->second);
string lala = buff;
cout << lala;
return lala;
}

int main()
{
map<string, double> hm;
hm.insert(pair<string,double>("1", 0.1));
      
hm.insert(pair<string, double>(((string)"2").c_str(), 0.3));
hm.insert(pair<string, double>(((string)"3").c_str(), 0.1));
hm.insert(pair<string, double>(((string)"4").c_str(), 0.95));
hm.insert(pair<string, double>(((string)"5").c_str(), 0.05));

string s = getRandomPrize(hm);
system("pause");
return 0;
}
我写的我觉得还是有错。。。。
发表于 2016-04-21 09:17:27 回复(0)
根本看不懂这题的意思。。。
发表于 2016-01-21 20:24:32 回复(0)
谁来解答一下啊
发表于 2015-12-19 23:34:59 回复(1)