我想生成八位(uint8_t)随机数,这样我就排除了已经指定的一组众所周知的数字。基本上从0x00到0xFF的数字,但我有一定范围内的数字,我不想出现。如何生成8位(伪)随机数,以便排除某些已知数字?
我想只是用允许的数字填充矢量,然后选择一个(伪)随机索引并使用它。
我怀疑他们可能是严重缺乏这个,所以寻找线索/建议。该解决方案不一定是火箭科学档次,但只是很简单的“出现”随机:)
编辑:我不想使用外部库,例如升压,因为我对ARM的嵌入式解决方案
编辑工作:我不支持C++ 11
我想生成八位(uint8_t)随机数,这样我就排除了已经指定的一组众所周知的数字。基本上从0x00到0xFF的数字,但我有一定范围内的数字,我不想出现。如何生成8位(伪)随机数,以便排除某些已知数字?
我想只是用允许的数字填充矢量,然后选择一个(伪)随机索引并使用它。
我怀疑他们可能是严重缺乏这个,所以寻找线索/建议。该解决方案不一定是火箭科学档次,但只是很简单的“出现”随机:)
编辑:我不想使用外部库,例如升压,因为我对ARM的嵌入式解决方案
编辑工作:我不支持C++ 11
#include <iostream>
#include <algorithm>
#include <ctime>
int main()
{
srand(time(0));
int exclude [] = {4,6,2,1};
// Test Values for Exclude
std::sort(exclude, exclude + 4);
int test = 0;
for (int i = 0; i < 50; ++i)
{
// While we haven't gotten a valid val.
while (std::binary_search(exclude, exclude + 4, test = (rand() % 256)));
std::cout << test << std::endl; // Print matched value
}
return 0;
}
我认为这会比@ IceCoder的解决方案快一点。
unsigned char unwanted[] = {1, 2, 3};
int unwanted_len = 3;
bool found;
do
{
unsigned char val = static_cast<unsigned char>(rand() % 0xff);
found = true;
for(int i = 0; i < unwanted_len; i++)
if(unwanted[i] == val)
found = false;
} while(!found);
把它放在一个函数中,你就完成了。您必须包含cstdlib
才能使其工作。
编辑:
其他可能性(因为你工作的范围限制):
bool nums[256];
void init_r()
{
for(int i = 0; i < 256; i++)
nums[i] = true;
}
void get_rnd()
{
int n;
do
{
n = rand() % 256;
} while(nums[n] == false);
return n;
}
您可以通过作用于nums
阵列上禁用任何你想要的号码。
什么是预期的运行时间? :-) –
这将不会有一个非常愉快的统计分布。 – bmargulies
我是一个缓慢的算法,但是当他问简单的代码时,会更简单些?此外,由于可接受结果的范围仅为256,因此大量不需要的数组将使其无法使用。我现在正在添加一个新的算法。 – AlQafir
一个小的通用方法是实现一个发生器适配器来过滤发生器。然后,您可以以任何您想要的方式轻松实现谓词。在这里我使用vector
,但set
可以做得很好,并可能提供更好的性能。
随机发生器由TR1
和C++11
随机设施提供。
#include <set>
#include <algorithm>
#include <vector>
#include <iostream>
#include <random>
#include <cstdint>
#include <functional>
template<typename Generator, typename Predicate>
struct filtered_generator {
Generator g;
Predicate p;
auto operator()() -> decltype(g()) {
auto tmp = g();
if(p(tmp))
return tmp;
else
return (*this)();
}
};
template<typename G, typename P>
filtered_generator<G, P> make_filter(const G& g, const P& p) {
return filtered_generator<G, P>{g, p};
}
int main()
{
std::mt19937 eng;
eng.seed(23);
std::uniform_int_distribution<std::uint8_t> dist(1, 10);
auto rnd = std::bind(dist, eng);
{
// using a vector
std::vector<uint8_t> forbidden = {1, 2, 3};
auto g = make_filter(rnd, [&forbidden](std::uint8_t t) {
return std::find(forbidden.begin(), forbidden.end(), t) == forbidden.end();
});
for(int i = 0; i < 20; ++i)
{
std::cout << static_cast<int>(g()) << std::endl;
}
}
// using a set
std::set<std::uint8_t> forbidden = {1, 2, 3};
auto g = make_filter(rnd, [&forbidden](std::uint8_t t) {
return forbidden.count(t) == 0;
});
for(int i = 0; i < 20; ++i)
{
std::cout << static_cast<int>(g()) << std::endl;
}
}
当发电机提供 一个result_type
的typedef,以消除decltype
的依赖和 lambda表达式将不得不进入仿函数C++ 03的适应应该是容易实现。
您的解决方案听起来不错。去吧。 (不知道这应该是一个答案或评论,但实际上没有什么需要添加的;从数组中随机选择元素总是会发生......) – sarnold
+1这是一种常用的方法来选取带有禁止值的随机数。 – Dalmas
如果您的禁止编号列表在运行时不会改变,并且如果256字节对您而言不是很多内存,那么我会说您的是最好的解决方案。 – TonyK