如何生成8位(伪)随机数,以便排除某些已知数字
How do I generate 8 bit (pseudo) random numbers so that I exclude certain known numbers?
我想生成8位(uint8_t)随机数,以便我排除一组已经指定的众所周知的数字。基本上从0x00到0xFF的数字,但我有一些数字在这个范围内,我不想出现。
我正在考虑用允许的数字填充一个向量,并选择一个(伪)随机索引并使用该索引。
我怀疑他们可能有严重的缺点,所以寻找线索/建议。解决方案不需要是火箭科学级别,但只要足够简单,"看起来"随机:)
编辑:我不想使用像boost这样的外部库,因为我正在开发ARM嵌入式解决方案
编辑:我不支持c++ 11
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
数组来禁用任何数字。
#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的解决方案快一点。
一种较小的通用方法是实现一个过滤Generator的Generator适配器。然后,您可以轻松地以您想要的任何方式实现谓词。这里我使用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;
}
}
当生成器提供时,c++ 03适配应该很容易实现一个result_type
类型定义来移除对decltype
的依赖而lambda必须变成函子
相关文章:
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 检查输入是否不是整数或数字
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- 如何用数字处理log(0)
- 最高有效数字侧的第N位
- 如何获取一个数字的前3位
- 查找最接近的大于当前数字的数字的索引
- 找到两对数字,使它们的乘积的绝对差最小化
- 我想做一个彼此不同但重复出现的数字
- 将数字转换为字母(例如:123 转换为一二三)
- C++如何计算用户输入的数字中的偶数位数
- 如何在C++中确定文本文件中的元素是字符还是数字
- 打印数字图案
- C++问题:用户认为数字1-100,程序提出问题不超过6次即可得到答案。无法正确
- C++:如何在从给定缓存中排除数字的同时生成随机数
- 程序以计数5位数字的数量可排除3,而其中没有6,7,8和9
- 循环排除特定数字的倍数
- 如何生成8位(伪)随机数,以便排除某些已知数字
- 从随机范围中排除一个数字