How do you create an enumeration of random values?

青春壹個敷衍的年華 提交于 2019-12-24 19:19:49

问题


How can I get an IEnumerable of random values? I'm disappointed the class Random doesn't implement IEnumerable<int>.


回答1:


Write an extension method that will yield return new values.

public static IEnumerable<int> GetRandomValues(this Random instance)
{
    while(true)
    {
        yield return instance.Next();
    }
}



回答2:


You can implement this yourself fairly easily, for example

public IEnumerable<int> RandomInts(int below)
{
    Random r = new Random();
    while (true) yield return r.Next(below);
}



回答3:


The some problematic points off having an IEnumerable<int> instance for the Random class are

  • The random generator has infinitely many elements, therefore using the foreach construct or an loop over the elements will never terminate.
  • The IEnumerator<int> instance which getEnumerator from IEnumerable<int> should return has a function Reset which resets the enumerator to the begin of the collection. Assuming correct behaviour this should return the first generated random number, as it was generated in the past.

The last problem can be solved in at least two ways,

  • Keeping an list of already generated values, this might not be very memory efficient, but at least ensures that it will always return the same values after resetting.
  • Keeping the starting seed and when Reset is called a new generator can be instantiated with the previous seed. All other random generating methods of Random should be hidden to prevent the, from being accessed.

As the bookkeeping method is not very good, I would go for the second version. Which is quite a large class, as you can see below.

public class RandomInt : IEnumerable<int>
{
    int seed;

    public RandomInt ()
    {
        seed = new Random ().Next();
    }


    public IEnumerator<int> GetEnumerator ()
    {
        return new InternalEnumerator (seed);
    }

    protected class InternalEnumerator : IEnumerator<int>
    {
        Random randomGen;
        int current;
        int seed;

        protected InternalEnumerator (int seed)
        {
            this.seed = seed;
        }

        #region IEnumerator implementation
        public bool MoveNext ()
        {
            if (randomGen == null)
                randomGen = new Random (seed);
            current = randomGen.Next();
            return true;
        }

        public void Reset ()
        {
            randomGen = null;
        }

        public int Current {
            get {
                if (randomGen == null)
                    throw new InvalidOperationException ("Enumerator in reset state");
                return current;
            }
        }
        #endregion
    }
}


来源:https://stackoverflow.com/questions/11435285/how-do-you-create-an-enumeration-of-random-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!