如何在c / c ++中的unsigned char数组中生成n个随机1?
这是一个与我刚才提出的问题不同的问题,而且更具挑战性。
我有一个unsigned char数组,比如unsigned char A [16]。 我需要生成一个掩码向量,我将应用于我的数组A [16]。
它应包含n个’1’,其中0 <n <16 * 8(掩码向量可以是数组B [16],只要数组中有n个'1'即可
我还需要在向量中随机分布这n个’1’。
我怎么能用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
生成随机(i,j)
数字对,其中i < 16
且j < 8
。 如果未设置位置B[i]&(1<
一些代码(未经测试):
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 #include #include 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; } } }
当该程序运行时,它将尝试从0
到16*8
每个n
值,并生成一个n
位的随机掩码,然后validation是否设置了n
位。 如果发生任何错误(对于某个n
值,设置了一些k!=n
位),则输出一条消息。
如果我将条件更改为if ( (B[i]^mask) != 0 )
,我会在输出中得到一致的错误。 每次运行都会产生至少1条错误消息。 原始条件if ( (B[i]&mask) == 0 )
始终产生0错误消息。
你有一个16个unsigned char
的数组,可以看作16 * 8位。 要生成一个n
1位的随机掩码,在[0,16 * 8]范围内生成一个随机位置,并将相应的位设置为1.如果该位先前为零,那么您刚刚添加了一个位。arrays。 重复此操作,直到添加了n
位。