随机种子递归函数.我该怎么做呢?
本文关键字:我该怎么做 递归函数 种子 随机 | 更新日期: 2023-09-27 18:13:29
我有一个递归函数,在函数中从数组中随机选择一个元素,但无论我做什么,我总是得到相同的种子。
static Random rand = new Random();
public String spintaxParser(String s)
{
if (s.Contains('{'))
{
int closingBracePosition = s.IndexOf('}');
int openingBracePosition = closingBracePosition;
while (!s[openingBracePosition].Equals('{'))
openingBracePosition--;
String spintaxBlock = s.Substring(openingBracePosition, closingBracePosition - openingBracePosition + 1);
String[] items = spintaxBlock.Substring(1, spintaxBlock.Length - 2).Split('|');
s = s.Replace(spintaxBlock, items[rand.Next(items.Length)]);
return spintaxParser(s);
}
else
{
return s;
}
}
在递归函数中处理随机的最好方法是什么?
在递归函数的作用域之外声明Random
对象的单个(静态)实例,然后从递归函数内部调用该实例。
Random
的默认构造函数将自动使用当前时间戳为其种子,因此您将一遍又一遍地获得相同的值,因为您不断创建Random
对象的新实例。
编辑:另外,你可以试试这个,虽然它绝对不是理想的。比起这种方法,我更喜欢单个Random
实例或静态种子。
Random r = new Random( Guid.NewGuid().GetHashCode() );
如果你张贴代码会有帮助。但如果没有,我会用我的精神力量,我猜你在用这样的模式
void MyRecursiveFunction() {
var index=new Random().Next(...);
...
}
如果为真,则修复方法是更改代码,使其只执行一次"new Random()"并将其传递(或将其存储在一些适当的实例变量中),而不是每次都构造一个新的。
将Random
作为参数传递给递归函数,并使用传递的实例每次从中获取下一个值
public void Recurse(object param, Random rand)
{
...
var val = rand.Next();
//use the value ...
Recurse(obj, rand);
}
Recurse(arg, new Random());
显然,递归将以某种方式触底,但这说明了原则。
我建议您在递归函数本身中包含随机对象。这个测试应该证明你不会总是得到相同的int。
[Test]
public void TestSpintaxRandom()
{
spintaxParser("{|||{|||{|||{|||{|||{|||{|||{|||}}}}}}}}", new Random());
}
public String spintaxParser(String s, Random r)
{
if (s.Contains('{'))
{
var closingBracePosition = s.IndexOf('}');
var openingBracePosition = closingBracePosition;
while (!s[openingBracePosition].Equals('{'))
openingBracePosition--;
var spintaxBlock = s.Substring(openingBracePosition, closingBracePosition - openingBracePosition + 1);
var items = spintaxBlock.Substring(1, spintaxBlock.Length - 2).Split('|');
var next = r.Next(items.Length);
Console.WriteLine(next);
s = s.Replace(spintaxBlock, items[next]);
return spintaxParser(s, r);
}
return s;
}