如何在dynamic_bit
集中找到随机位1(或0)?
示例:
bitset: 101101
index : 012345
find_random_bit_1() return 3
find_random_bit_0() return 4
答案 0 :(得分:2)
最简单的方法是继续选择位,直到找到你想要的位:
template <typename T, typename Alloc, typename Rnd = boost::mt19937>
size_t select_random_bit(boost::dynamic_bitset<T, Alloc> const& bs, Rnd& random, bool target = true) {
boost::uniform_int<size_t> pick(0,bs.size()-1);
if (bs.empty() || (bs.all() && !target) || (bs.none() && target))
throw std::range_error("select_random_bit");
while(true) {
auto index = pick(random);
if (bs[index] == target)
return index;
}
throw std::logic_error("select_random_bit");
}
最重要的是前置条件检查以避免无限循环。当然,对于非统一数据,性能可能不好,但这是获得公平分配的最简单方法
<强> Live On Coliru 强>
#include <boost/dynamic_bitset.hpp>
#include <boost/random.hpp>
#include <iostream>
#include <stdexcept>
template <typename T, typename Alloc, typename Rnd = boost::mt19937>
size_t select_random_bit(boost::dynamic_bitset<T, Alloc> const& bs, Rnd& random, bool target = true) {
boost::uniform_int<size_t> pick(0,bs.size()-1);
if (bs.empty() || (bs.all() && !target) || (bs.none() && target))
throw std::range_error("select_random_bit");
while(true) {
auto index = pick(random);
if (bs[index] == target)
return index;
}
throw std::logic_error("select_random_bit");
}
boost::dynamic_bitset<> generate_testdata(boost::mt19937& rng) {
boost::dynamic_bitset<> bs(1024+rng()%1024); // [1024,2048) bits
boost::uniform_smallint<uint8_t> gen(0, 1);
for(size_t i = 0; i < bs.size(); ++i)
bs[i] = gen(rng);
return bs;
}
int main() {
using namespace boost;
mt19937 rng(42); // seed it
auto data = generate_testdata(rng);
std::cout << data.count() << " out of " << data.size() << " bits are set\n";
std::cout << "\nTrue: ";
for (int i = 0; i <10; ++i)
std::cout << select_random_bit(data, rng/*, true*/) << " ";
std::cout << "\nFalse: ";
for (int i = 0; i <10; ++i)
std::cout << select_random_bit(data, rng, false) << " ";
}
打印10个真假和10个假位,例如:
562 out of 1126 bits are set
True: 1104 394 684 716 624 492 102 817 392 616
False: 335 589 971 785 1069 948 865 290 51 652