簡體   English   中英

如何在c / c ++中的無符號char數組中生成n個隨機1?

[英]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 < 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;
        }
    }
}

運行此程序時,它將嘗試從016*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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM