如何产生n个随机1S在C / C ++无符号的字符数组?(How to generate n ran

2019-10-28 15:19发布

这是一个我刚问了一个不同的问题,这是更具挑战性。

我有一个无符号的字符阵列,说无符号字符A [16]。 我需要生成哪个我将适用于我的数组A [16]的掩模矢量。

它应该包含n个“1',其中0 <N <16×8(掩模载体可以是一个数组B [16]只要有n个的数目”阵列中的1'S)

我还需要在向量随机分布的“1的这些n个。

我怎样才能做到这一点在C / C ++?

谢谢!

编辑:我的想法是:我会产生N个随机数(检查要做的需求,以确保所有的n个数字是不一样的),并将其存储在阵列TMP [N]。 然后掩模基础上产生偏移。

srand(time(0));
for(i = 0; i < n; i++){
  for(j = 0; j < i; j++) 
    while(tmp[i] == tmp[j])  // to make sure all n random numbers are different
      tmp[i] = rand()%128;

unsigned char mask[16] 
for(i = 0; i < n; i++) 
  mask[16] |= (1 << tmp[i]);  //generate mask

Answer 1:

产生随机(i,j)对数字,其中的i < 16j < 8 如果在位置的位B[i]&(1<<j)没有设置,将其设置并递增“计数”。 循环直到“计数”达到“N”。

的码A位(未测试):

void generate_n_bit_mask ( unsigned char B[], int n )
{
    // avoid infinite loop later on.
    for ( int i=0; (i < 16); ++i ) {
        B[i] = 0;
    }
    // invariant: k is number of currently masked bits.
    for ( int k = 0; (k < n); )
    {
        // select bit at random.
        int i = rand() % 16;
        int j = rand() %  8;
        unsigned char mask = 1 << j;
        // set it if not selected previously.
        if ( (B[i]&mask) == 0 ) {
            B[i] |= mask, ++k;
        }
    }
}

锻炼,接受挑战:去掉魔法常数16从代码。

编辑 :在您的意见建议修改包含一个讨厌的错误。 下面是一个测试程序与位分布在你的输出掩码的方式来播放。

#include <iostream>
#include <iomanip>
#include <ctime>

void generate_n_bit_mask ( unsigned char B[], int n )
{
    // avoid infinite loop later on.
    for ( int i=0; (i < 16); ++i ) {
        B[i] = 0;
    }
    // invariant: k is number of currently masked bits.
    for ( int k = 0; (k < n); )
    {
        // select bit at random.
        int i = std::rand() % 16;
        int j = std::rand() %  8;
        unsigned char mask = 1 << j;
        // set it if not selected previously.
        if ( (B[i]&mask) == 0 ) {
            B[i] |= mask, ++k;
        }
    }
    int j = 0;
}

// count number of set bits in a byte.
int bit_count ( unsigned char x )
{
    int n = 0;
    for ( int i = 0; (i < 8); ++i ) {
        n += ((x >> i) & 1);
    }
    return (n);
}

// count number of set bits in 16 bytes.
int total_bit_count ( unsigned char B[] )
{
    int n = 0;
    for ( int i = 0; (i < 16); ++i ) {
        n += bit_count(B[i]);
    }
    return (n);
}

int main ( int, char ** )
{
    std::srand(std::time(0));
    unsigned char B[16];
    // for all possible values of "n"
    for ( int i = 0; (i <= 16*8); ++i )
    {
        // generate a 16 byte mask with "n" set bits.
        generate_n_bit_mask(B, i);
        // verify that "n" bits are set.
        int n = total_bit_count(B);
        if ( n != i ) {
            std::cout << i << ": " << n << std::endl;
        }
    }
}

当运行这个程序,它会尝试的每个值n016*8和生成一个随机掩码n位,然后验证准确n位设置。 如果出现任何错误(的某些值n ,一些k!=n位被设置),消息被输出。

如果我改变的条件if ( (B[i]^mask) != 0 )我得到的输出一致的错误。 每次运行产生至少1错误消息。 原来的状态if ( (B[i]&mask) == 0 )一致地产生0的错误消息。



Answer 2:

你有16个的阵列unsigned char s,这可以被看作是16×8比特。 产生具有随机掩码n在它为1点的位,产生在范围[0,16×8的随机位置),并相应的位设置为1。如果该位是以前零,则刚添加一个位到阵列。 重复此,直到添加n位。



文章来源: How to generate n random 1s in an unsigned char array in c/c++?
标签: c++ c random