如果您使用Random.Range()
生成值,是否有办法排除范围内的某些值(例如:选择1到20之间的数字,但不是6到8之间的数字)?
答案 0 :(得分:12)
执行此操作的最佳方法是使用您喜欢的生成器生成1到17之间的整数n
,然后使用
if (n > 5){
n += 3;
}
如果您在1到20之间采样然后丢弃值,则可能会引入统计异常。 (例如,如果您的随机数生成器是线性同余生成器,则您的方差将太高:尝试并查看。)
答案 1 :(得分:10)
所以你实际上想要17
(20 - 3)个不同的值
[1..5] U [9..20]
你可以实现类似的东西:
// Simplest, not thread-safe
private static Random random = new Random();
...
int r = (r = random.Next(1, 17)) > 5
? r + 3
: r;
在一般(和复杂)的情况下,我建议生成所有可能值的数组,然后采取 来自它的项目:
int[] values = Enumerable
.Range(1, 100) // [1..100], but
.Where(item => item % 2 == 1) // Odd values only
.Where(item => !(item >= 5 && item <= 15)) // with [5..15] range excluded
//TODO: Add as many conditions via .Where(item => ...) as you want
.ToArray();
...
int r = values[random.Next(values.Length)];
答案 2 :(得分:5)
是的,您可以在LINQ中简单地使用where
语句
var list = Enumerable.Range(1, 20).Where(a => a < 6 || a > 8).ToArray();
其他方式没有LINQ
public IEnumerable RangeBetween()
{
foreach (var i in Enumerable.Range(1, 20))
{
if (i < 6 || i > 8)
{
yield return i;
}
}
}
编辑:现在我看到的不是一个严格的C#问题。它会影响Unity
和Random
。但是对于完整的答案我觉得你使用Enumerable.Range
上面的代码然后使用它来生成数字:
list[Random.Next(list.Length)];
答案 3 :(得分:1)
另一种方法是创建一个有效返回值的数组,然后随机选择一个:
void Main()
{
var rng = new Random();
var validValues = Enumerable.Range(1, 20).Except(new int[] {6, 7, 8}).ToArray();
for (int i = 0; i < 25; i++)
{
Console.Write(validValues[rng.Next(0, validValues.Length)]);
Console.Write(" ");
}
}
编辑:哎呀!刚刚注意到这是针对Unity3D的,所以这个例子可能不合适。但它可以使用标准Random
类。
答案 4 :(得分:0)
如果r在6-8的范围内,则会选择不同的随机数。
int r = 0;
do
{
r = Random.Next(20);
} while (r >= 6 && r <= 8)
答案 5 :(得分:-1)
我将在这个问题上投入2美分。这是一个完整的类,显示了一个生成随机数的方法,不包括您选择的数字以及如何使用它。
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
public class test2 : MonoBehaviour {
System.Random rand;
int[] excludelist;
void Start()
{
rand = new System.Random();
excludelist = new int[] { 5,9,3};
for(int i = 0; i<20;i++)
{
Debug.Log(MakeMeNumber(excludelist));
}
}
private int MakeMeNumber(params int[] excludeList)
{
var excluding = new HashSet<int>(excludeList);
var range = Enumerable.Range(1, 20).Where(i => !excluding.Contains(i));
int index = rand.Next(0, 20 - excluding.Count);
return range.ElementAt(index);
}
}
答案 6 :(得分:-2)
我已经创建了专门针对该案例设计的资产(已付款)。
它仅包含一些有用的函数,这些函数根据给定的间隔(例如,X和Y之间(不包括Z))生成随机数。
您的示例(介于1到20之间,但不包括6到8)将由第三个函数RandomExclude.RandomInt(int,int,Vector2)覆盖。第一个int是可能的最低值,第二个int是最高的值,Vector2是我们排除的间隔。在您的情况下,看起来像这样:
int ourOutcome = RandomExclude.RandomInt(1,20,新的Vector2(6,8));
资产包含更多类似的功能,它们使您可以生成一个排除一个数字,一个排除几个数字或排除几个间隔的整数。
所有详细的实施说明已包含在资产本身中,所以请不要担心。
https://assetstore.unity.com/packages/tools/input-management/random-exclude-133786
随时尝试!