c++ - 如何在 C/C++ 中的 unsigned char 数组中生成 n 个随机 1?

标签 c++ c random

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

我有一个无符号字符数组,比方说 无符号字符 A[16]。 我需要生成一个掩码 vector ,我将其应用于我的数组 A[16]。

它应该包含 n 个“1”,其中 0 < n < 16*8(掩码 vector 可以是数组 B[16],只要数组中有 n 个“1”)

我还需要 vector 中随机分布的这 n 个“1”。

我如何在 c/c++ 中执行此操作?

谢谢!

编辑: 我的想法是这样的: 我将生成 n 个随机数(需要进行检查以确保所有 n 个数字都不相同)并将它们存储在数组 tmp[n] 中。然后根据shifting生成mask。

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 < 16j < 8 .如果位在B[i]&(1<<j)未设置,设置它并增加“计数”。循环直到“count”达到“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;
        }
    }
}

当这个程序运行时,它会尝试 n 的每一个值来自 016*8并使用 n 生成一个随机掩码位,然后准确地验证 n位被设置。如果发生任何错误(对于 n 的某些值,某些 k!=n 位已设置),将输出一条消息。

如果我将条件更改为 if ( (B[i]^mask) != 0 ) ,我在输出中得到一致的错误。每次运行都会产生至少 1 条错误消息。原状if ( (B[i]&mask) == 0 )始终产生 0 个错误消息。

关于c++ - 如何在 C/C++ 中的 unsigned char 数组中生成 n 个随机 1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7749497/

相关文章:

C++ 为什么我的类仍然是抽象的?

c++ - 使用构造函数参数实例化类对象和不带参数 C++ 的 * 运算符之间的区别

c++ - "Private memory"尽管对象被破坏,但捕获 bad_alloc 后未释放

c - TCP 传入数据包记录器

c - 直接在二维数组中执行 fisher - yates shuffle

R - 通过随机选择组成的数据帧来创建新的数据帧

c++ - 使用 Qt 在 Windows 桌面上使用蓝牙 LE

c - 用位移位代替加法运算

linux - urandom 有多随机?

c - 理解为什么我需要 malloc