如何在dynamic_bit集中找到随机位1(或0)?

时间:2015-05-31 14:49:14

标签: boost

如何在dynamic_bit集中找到随机位1(或0)?

示例

bitset: 101101
index : 012345

find_random_bit_1() return 3
find_random_bit_0() return 4

1 个答案:

答案 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