[英]How to generate n random 1s in an unsigned char array in c/c++?
这是一个与我刚刚问过的问题不同的问题,它更具挑战性。
我有一个无符号字符数组,比如说无符号字符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<<j)
,则对其进行设置并递增“计数”。 循环直到“计数”达到“ n”。
一点代码(未经测试):
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;
}
}
}
运行此程序时,它将尝试从0
到16*8
每个n
值,并生成一个具有n
位的随机掩码,然后验证是否正确设置了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。如果该位以前为零,则只需将一个位添加到阵列。 重复此过程,直到您添加了n
位。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.