我想生成0到5范围内的随机数,但是例如,在某些情况下我不需要数字3,我只需要0、1、2、4、5。如何生成范围内的随机数,但可以选择排除我不需要的数字。
问问题
12262 次
6 回答
5
这是另一个使用 C++ 11 的现代特性的解决方案。
#include <functional>
#include <iostream>
#include <ostream>
#include <random>
int main()
{
std::random_device rd;
unsigned long seed = rd();
std::cout << "seed " << seed << std::endl;
std::mt19937 engine(seed);
// Distribution {0, 1, 2, 4, 5}
std::discrete_distribution<> dist {{1, 1, 1, 0, 1, 1}};
auto rng = std::bind(dist, std::ref(engine));
const int n = 10;
for (int i = 0; i != n; ++i)
{
int x = rng();
std::cout << x << std::endl;
}
return 0;
}
于 2014-08-31T04:48:52.513 回答
2
您要排除的数字在编译时是否已知?然后一个简单的查找表应该做:
static int table[] = {0, 1, 2, 4, 5};
int index = rand() % (sizeof table / sizeof *table);
int number = table[index];
当然,rand()
这是一个可怕的伪随机数生成器,但那是另一个话题。
于 2013-02-17T10:35:57.603 回答
0
只需在循环中丢弃 3:
template <typename Rng>
int rand_no_three (Rng& rng)
{
std::uniform_int_distribution<> dist (0, 5);
int c;
do {
c = dist (rng);
} while (c == 3);
return c;
}
示例用法:
std::mt19937 rng;
int c = rand_no_three (rng);
于 2013-02-17T10:33:42.653 回答
0
这是一种在没有查找表的情况下执行此操作的方法,以防您有内存限制。
int map_fun(int i)
{
switch(i)
{
case 3: return 4;
case 4: return 5;
}
return i;
}
int main()
{
int i= map_fun(random_between(0, 4));
}
于 2013-02-17T10:40:51.250 回答
0
这是使用这篇文章中的 java 代码的示例:如何在一个范围内生成一个随机数但排除一些? 翻译成c++。
这有点通用,并且没有使用不必要的循环。
我还做了一个分布、范围和出现 - 检查这个程序:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <time.h>
#include <map>
using namespace std;
int getRandomWithExclusion(int start, int end, vector<int> &excludes){
unsigned int max = end - start + 1 - excludes.size();
int random = start+(rand() % max);
for (unsigned int i = 0;i<excludes.size();i++) {
int ex = excludes[i];
if (random < ex){
break;
}
random++;
}
return random;
}
int main()
{
srand (time(NULL));
vector<int> excl;
map<int,int> distMap;
excl.push_back(-2);
excl.push_back(3);
for(int i=0;i<100000;i++){
int val = getRandomWithExclusion(-5,5,excl);
if (distMap.find(val) == distMap.end()){
distMap[val]=0;
}
int key = distMap[val]+1;
distMap[val]=key;
}
map<int, int>::iterator p;
for(p = distMap.begin(); p != distMap.end(); p++) {
cout << p->first <<" occurs " <<p->second << endl;
}
cout << "seems legit: even distributed and correct" << endl;
return 0;
}
于 2013-02-17T11:12:00.563 回答
0
这个 c++ 函数应该处理这个任务:
int getRandomIntExcludingRange(int start, int end, int start_range, int end_range) {
// handle bad input gracefully
if (start > end) {
std::swap(start, end);
}
if (start_range > end_range) {
std::swap(start_range, end_range);
}
std::clamp(start_range, start, end);
std::clamp(end_range, start, end);
auto range_length = end_range - start_range;
auto adj_end = end - range_length;
auto shifted_end = adj_end - start;
int rand_int = (rand() % shifted_end) + start;
if (rand_int >= start_range) {
rand_int = (rand_int - start_range) + end_range;
}
return rand_int;
}
于 2021-01-22T20:04:50.180 回答