2014-11-23 36 views
2

这是我用来生成随机字节数组的代码。这是完全没问题,唯一的是 有一个(或多个)我不想要的数字。我的问题是,如何确保这些不需要的数字不包含在结果中,而不必经过每个结果?生成随机字节数组而不会忽略值

Random rnd = new Random(); 
    Byte[] bytes = new Byte[50]; 
    rnd.NextBytes(bytes); 

对于一个字节,我使用这个函数;

int b = rnd.Next(min, (max + 1)) 
    return (byte) b; 

其中我可以控制结果范围,但重复调用此函数不会给出好的结果。

+0

你不想要什么号码?你能展示一个包含这样的数字的样例输出,以及你期望它的样子吗? – 2014-11-23 15:48:02

+0

“,但重复调用此函数不会给出好的结果。”这是什么意思?你每次打电话时都收到相同的号码吗? – 2014-11-23 15:48:15

回答

4

您的问题可以用蒙特卡洛算法轻松解决。这就是@SteveLillis正在做的事情,但这是一个不完整的答案。所以这里是完整的。

void Main() 
{ 
    var exclusions = new HashSet<byte> { 1, 200, 58, 11, 66, 9 }; 

    var results = RandomBytes() 
        .Where(b => exclusions.Contains(b) == false) 
        .Take(50) 
        .ToArray(); 
} 

public IEnumerable<byte> RandomBytes() 
{ 
    var random = new Random(); 
    byte[] buffer = new byte[32]; 
    while(true) 
    { 
     random.NextBytes(buffer); 
     foreach(var ret in buffer) 
     { 
      yield return ret; 
     } 
    } 
} 

RandomBytes()是一个随机字节流,很简单吧?

然后我们排除任何我们不喜欢的流,Where(b => exclusions.Contains(b) == false)。哈希集是为了“效率”,但它不会帮助byte(只是因为习惯)。

Take(50),我们只从流中获得50个。

ToArray以数组形式给出结果。

+0

产量和拉姆达... COOL @Aron !!!但我不明白为什么32缓冲区阵列?一个数组是好的,因为它是一个随机数,你不这么认为吗? – 2014-11-23 19:59:05

+0

@sambyte我不完全确定'.NextBytes'的实现是什么。一般来说,当他们以这种方式公开功能时,通常使用“较大”缓冲区运行起来更便宜。但是,是的...在功能上,'byte [1]'将完全相同。 – Aron 2014-11-24 03:06:08

0

如果数字不太可能继续提升,您可以继续尝试,直到生成“好”数字。

var badNumbers = new int[] { 244, 100 }; 
int b = 0; 
do 
{ 
    b = rnd.Next(min, (max + 1)); 
} while (badNumbers.Contains(b)); 

此外,请确保你宣布你的随机对象,并反复使用它,不要让实例化一个新的,因为默认情况下的种子是从时间采取,如果你实例2个随机量过快一个之后,他们会生成相同的号码。

0

您可以在单独的数组中生成允许值(相对于最小值,最大值和忽略的值),并将其用于目标数组生成。我们来考虑下面的例子。

帮助功能:

byte[] GenerateAllowableValues(byte min, byte max, byte[] ignore) 
{ 
    var list = new List<byte>(); 
    for (byte i = min; i <= max; i++) 
    if (!ignore.Contains(i)) 
     list.Add(i); 
    return list.ToArray(); 
} 

byte[] GenerateRandomArray(Random random, byte[] allowableValues, int length) 
{ 
    var array = new byte[length]; 
    for (int i = 0; i < length; i++) 
    array[i] = allowableValues[random.Next(allowableValues.Length)]; 
    return array; 
} 

用法:

void Main() 
{ 
    var random = new Random(42); 
    var allowableValues = GenerateAllowableValues(10, 20, new byte[] { 12, 15 }); 
    var randomArray = GenerateRandomArray(random, allowableValues, 5); 
    foreach (byte b in randomArray) 
    Console.WriteLine(b); // 18 11 11 16 11 
} 
0

构建你想排除那些你不这样做,然后选择一个随机元素从阵列50倍的字节数组;

var rnd = new Random(); 
var exclusions = new byte[] { 1, 200, 58, 11, 66, 9 }; 
var candidates = Enumerable.Range(0, 255).Where(i => !exclusions.Contains((byte)i)).ToArray(); 

var results = new byte[50]; 
for (var i = 0; i < results.Length; i++) 
{ 
    results[i] = (byte)candidates[rnd.Next(0, candidates.Length - 1)]; 
}