我想生成0到5范围内的随机数,但是例如,在某些情况下我不需要数字3,我只需要0,1,2,4,5。如何生成随机数在范围内,但可以选择排除我不需要的数字。
答案 0 :(得分: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;
}
答案 1 :(得分:2)
您想要在编译时排除的数字是否已知?然后一个简单的查找表应该:
static int table[] = {0, 1, 2, 4, 5};
int index = rand() % (sizeof table / sizeof *table);
int number = table[index];
当然,rand()
是一个可怕的伪随机数生成器,但这是一个不同的主题。
答案 2 :(得分: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);
答案 3 :(得分: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));
}
答案 4 :(得分:0)
这是使用此帖子中的java代码的示例:How can I generate a random number within a range but exclude some? 翻译成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;
}
答案 5 :(得分: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;
}