如何生成n个随机1S在C / C ++的无符号的字符数组? [英] How to generate n random 1s in an unsigned char array in c/c++?

查看:124
本文介绍了如何生成n个随机1S在C / C ++的无符号的字符数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我有一个无符号的字符数组,说
unsigned char型A [16]。
我需要生成,我将适用于我的数组A [16]面具载体。

它应该包含的'1',在0℃n个; N'LT; 16 * 8(掩模载体可以是一个排列B [16]只要有n阵列中的'1'编号)

我还需要在向量随机分布的1的这些n个。

我怎样才能做到这一点在C / C ++?

感谢您!

编辑:
我的想法如下:
我将产生n个(做检查需求,以确保所有的n号不相同)的随机数,并将其存储在数组TMP [n]的。然后面膜是基于移动产生的。

 函数srand(时间(0));
对于(i = 0; I< N;我++){
  为(J = 0; J< I; J ++)
    而(TMP [I] == TMP [J])//以确保所有N个随机数是不同的
      TMP [I] =兰特()%128;unsigned char型面膜[16]
对于(i = 0; I< N;我++)
  掩模[16] | =(1 <<;&下; TMP [I]); //生成面具


解决方案

生成随机(I,J)对数字,其中的I&LT ; 16 J&LT; 8 。如果在位置的位 B [I]及(1 LT;&LT; j)条未设置,设置和增加计数。循环直到算变为N。

code的位(未经测试):

 无效generate_n_bit_mask(unsigned char型B〔],INT N)
{
    //避免以后无限循环。
    的for(int i = 0;(I&LT; 16); ++ I){
        B〔Ⅰ〕= 0;
    }
    //不变:k是当前掩蔽的位数。
    对于(INT K = 0;(K&LT; N);)
    {
        //随机选择位。
        INT I =兰特()%16;
        INT J =兰特()%8;
        unsigned char型面膜= 1&LT;&LT;焦耳;
        //如果不选择previously设置。
        如果((B [1] - 安培;面罩)== 0){
            B〔I] | =面具,++ K表;
        }
    }
}

锻炼,接受挑战:去掉魔法恒 16 从code

修改:本修饰您的意见建议包含了一个讨厌的错误。下面是一个测试程序与位分布在输出面具的方式打球。

 的#include&LT;&iostream的GT;
#包括LT&;&了iomanip GT;
#包括LT&;&的ctime GT;无效generate_n_bit_mask(unsigned char型B〔],INT N)
{
    //避免以后无限循环。
    的for(int i = 0;(I&LT; 16); ++ I){
        B〔Ⅰ〕= 0;
    }
    //不变:k是当前掩蔽的位数。
    对于(INT K = 0;(K&LT; N);)
    {
        //随机选择位。
        INT I =的std ::兰特()%16;
        INT J =的std ::兰特()%8;
        unsigned char型面膜= 1&LT;&LT;焦耳;
        //如果不选择previously设置。
        如果((B [1] - 安培;面罩)== 0){
            B〔I] | =面具,++ K表;
        }
    }
    INT J = 0;
}//一个字节中设置位的计数。
INT BIT_COUNT(unsigned char型X)
{
    INT N = 0;
    的for(int i = 0;(I&LT; 8); ++ I){
        的n + =((X&GT; I标记)及1);
    }
    返回(N);
}//在16字节比特集合计数。
INT total_bit_count(unsigned char型B〔])
{
    INT N = 0;
    的for(int i = 0;(I&LT; 16); ++ I){
        N + = BIT_COUNT(B [I]);
    }
    返回(N);
}INT主(INT,CHAR **)
{
    的std ::函数srand(的std ::时间(0));
    unsigned char型B〔16〕;
    //对于n的所有可能的值
    的for(int i = 0;(I&LT; = 16 * 8); ++ I)
    {
        //生成带N位设置一个16字节的面具。
        generate_n_bit_mask(B,I);
        //验证n位被设置。
        INT N = total_bit_count(B);
        如果(N!= 1){
            性病::法院LT&;&LT; I&LT;&LT; :&所述;&下; N'LT;&LT;的std :: ENDL;
        }
    }
}

在运行此程序,它会尝试 N 0 16 * 8 并产生 N 位,然后验证准确 N 位设置。如果出现任何错误(为 N ,有些 K!= N 位设置一定的价值),一条消息输出。

如果我更改了条件 IF((B [I] ^面膜)!= 0),我得到的输出一致的错误。每次运行产生至少1的错误消息。原状 IF((B [1] - 安培;面罩)== 0)。一贯产生0的错误消息

This is a different question from the one I just asked and it is more challenging.

I have an unsigned char array, say unsigned char A[16]. I need to generate a mask vector which i will apply to my array A[16].

It should contain n number of '1's, where 0 < n < 16*8 (The mask vector can be an array B[16] as long as there are n number of '1's in the array)

I also need these n number of '1's distributed randomly in the vector.

How can I do this in c/c++?

Thank you!

Edit: My thought is as follows: I will generate n random numbers (checking needs to be done to make sure all n numbers are not the same) and store them in array tmp[n]. Then mask is generated based on shifting.

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

解决方案

Generate random (i,j) pair of numbers, where i < 16 and j < 8. If the bit at position B[i]&(1<<j) is not set, set it and increment "count". Loop until "count" reaches "n".

A bit of code (untested):

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;
        }
    }
}

Exercise, for the challenge: remove magic constant 16 from the code.

Edit: The modification suggested in your comments contains a nasty bug. Here is a test program to play with the way bits are distributed in your output mask.

#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;
        }
    }
}

When this program is run, it will try every value of n from 0 to 16*8 and generate a random mask with n bits, then verify that exactly n bits are set. If any error occurs (for some value of n, some k!=n bits are set), a message is output.

If I change the condition to if ( (B[i]^mask) != 0 ), I get consistent errors in the output. Every run produces at least 1 error message. The original condition if ( (B[i]&mask) == 0 ) consistently produces 0 error messages.

这篇关于如何生成n个随机1S在C / C ++的无符号的字符数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆