2011-10-13 140 views
0

这是一个与我刚刚问过的问题不同的问题,它更具挑战性。如何在c/C++中的unsigned char数组中生成n个随机1?

我有一个无符号的字符阵列,说 无符号字符A [16]。 我需要生成一个面具矢量,我将应用到我的数组A [16]。

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

我还需要这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 
+2

你说你的要求很好,但你没有说明你做了什么,你的想法是解决这个问题。这看起来像家庭作业&除非你发布你的努力,这将很快关闭。 –

+0

这不是作业......但我可以发布我的努力 – drdot

回答

3

生成随机数(i,j)一对数字,其中i < 16j < 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; 
     } 
    } 
} 

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

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

+2

你真的需要一个逗号运算符吗? –

+0

它应该是'j'而不是'(j-1)'。 –

+1

@ K-ballo:是的。它强调两条指令实际上是算法中的一个合乎逻辑的步骤。 –

1

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