随机种子递归函数。我该怎么做?

时间:2011-11-04 14:21:22

标签: c#

我有一个递归函数,在函数中选择了一个数组中的随机元素,但无论我做什么,我都会得到相同的种子。

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的最佳方法是什么?

4 个答案:

答案 0 :(得分:3)

声明递归函数范围之外的Random对象的单个(静态)实例,然后从递归函数内部调用实例。

Random的默认构造函数将自动使用当前时间戳对其进行播种,因此您会反复获取相同的值,因为您不断创建Random对象的新实例。

编辑:此外,你可以试试这个,虽然它绝对不是理想的。我希望在这个方法上使用单个Random实例或静态种子。

Random r = new Random( Guid.NewGuid().GetHashCode() );

答案 1 :(得分:2)

如果你发布代码会有所帮助。但如果没有,我将使用我的通灵能力并猜测你正在使用这样的模式

void MyRecursiveFunction() {
  var index=new Random().Next(...);
  ...
}

如果为true,修复方法是更改​​代码,使其只执行一次“new Random()”并将其传递(或将其存储在某个适当的实例变量中),而不是每次都构造一个新代码。 p>

答案 2 :(得分:1)

Random作为参数传递给递归函数,并使用传递的实例每次从中获取下一个值。

public void Recurse(object param, Random rand)
{

  ...
  var val = rand.Next();
  //use the value ... 
  Recurse(obj, rand);
}

Recurse(arg, new Random());

显然,递归会以某种方式触底,但这证明了原理。

答案 3 :(得分:0)

我建议你在递归函数本身中包含随机对象。这个测试应该证明你不会总是得到相同的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;
    }