1

これまでのところ、シャッフルの次のコードがあります。

    public static IList<T> Shuffle<T>(this IList<T> list)
    {
        var rnd = new Random();
        return list.OrderBy(element => rnd.Next());
    }

そして、私はそれを次のように使用します。

    list = list.Shuffle();

みたいに使えるようになりたい

    list.Shuffle(); // like list.Reverse();

だから基本的に私は参照によってシャッフルしたい

私は次のコードを試しました、

    public static void Shuffle<T>(this ref IList<T> list)
    {
        var rnd = new Random();
        list.OrderBy(element => rnd.Next());
    }

しかし、うまくいきません。

どんな助けでも大歓迎です!

4

1 に答える 1

5

これはかなり前に書きました。おそらく、リンクされたアルゴリズムに当てはまることを確認する価値があります。この種のことは、微妙に間違えやすいことで有名です。

    //Fisher-Yates_shuffle http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
    private static readonly ThreadLocal<Random> RandomThreadLocal =
        new ThreadLocal<Random>(() => new Random());
    public static void Shuffle<T>(this IList<T> list, int seed = -1)
    {
        var r = seed >= 0 ? new Random(seed) : RandomThreadLocal.Value;
        var len = list.Count;
        for (var i = len - 1; i >= 1; --i)
        {
            var j = r.Next(i);
            var tmp = list[i];
            list[i] = list[j];
            list[j] = tmp;
        }
    }

以下のコメントに従って、柔軟性を高めるためにオーバーロードできます。

    private static readonly ThreadLocal<Random> RandomThreadLocal =
        new ThreadLocal<Random>(() => new Random());
    public static void Shuffle<T>(this IList<T> list, int seed)
    {
        list.Shuffle(new Random(seed));
    }

    public static void Shuffle<T>(this IList<T> list)
    {
        list.Shuffle(null);
    }

    public static void Shuffle<T>(this IList<T> list, Random rand)
    {
        var r = rand ?? RandomThreadLocal.Value;

        var len = list.Count;
        for (var i = len - 1; i >= 1; --i)
        {
            var j = r.Next(i);
            var tmp = list[i];
            list[i] = list[j];
            list[j] = tmp;
        }
    }
于 2012-11-06T17:10:01.550 に答える