36

私はしばらく検索して、これを見つけるのに苦労してきました.C#であるいくつかのランダムで一意の番号を生成しようとしています. を使用しており、シードSystem.Randomを使用しています:DateTime.Now.Ticks

public Random a = new Random(DateTime.Now.Ticks.GetHashCode());
private void NewNumber()
{
    MyNumber = a.Next(0, 10);
}

私はNewNumber()定期的に電話をかけていますが、問題は頻繁に繰り返し電話を受けることです。ランダムを宣言するたびに乱数を宣言していたため、乱数が生成されないため、宣言を関数の外に置いたので、提案した人もいました。を使用するよりも良い提案や方法はありSystem.Randomますか? ありがとうございました

4

17 に答える 17

27

私は定期的に NewNumber() を呼び出していますが、問題は、番号が繰り返されることが多いことです。

Random.Next番号が一意であることを保証するものではありません。また、範囲は 0 から 10 で、値が重複する可能性があります。重複が含まれていないかどうかを確認した後、リストを設定してリストにint乱数を挿入できる場合があります。何かのようなもの:

public Random a = new Random(); // replace from new Random(DateTime.Now.Ticks.GetHashCode());
                                // Since similar code is done in default constructor internally
public List<int> randomList = new List<int>();
int MyNumber = 0;
private void NewNumber()
{
    MyNumber = a.Next(0, 10);
    if (!randomList.Contains(MyNumber))
        randomList.Add(MyNumber);
}
于 2013-01-23T05:58:36.630 に答える
21

範囲が 0 ~ 9 しかない場合は、可能な int の配列をシャッフルしてみてください。これにより、数値生成での競合を回避できるという利点が追加されます。

var nums = Enumerable.Range(0, 10).ToArray();
var rnd = new Random();

// Shuffle the array
for (int i = 0;i < nums.Length;++i)
{
    int randomIndex = rnd.Next(nums.Length);
    int temp = nums[randomIndex];
    nums[randomIndex] = nums[i];
    nums[i] = temp;
}

// Now your array is randomized and you can simply print them in order
for (int i = 0;i < nums.Length;++i)
    Console.WriteLine(nums[i]);
于 2013-01-23T06:03:52.523 に答える
13

注、これはお勧めしません:)。 ここにも「ワンライナー」があります:

var result = Enumerable.Range(0,9).OrderBy(g => Guid.NewGuid()).ToArray();
于 2016-01-11T08:01:42.297 に答える
10

ここに投稿された他のアルゴリズムは均一なシャッフルを生成しないため、シャッフル アルゴリズムの正しい実装を投稿しています。

他の回答が述べているように、少数の値をランダム化するには、配列にそれらの値を入力し、配列をシャッフルしてから、必要な数の値を使用するだけです。

以下は、Fisher-Yates Shuffle (別名、Knuth Shuffle) の実装です。(そのリンクの「実装エラー」セクションを読んでください(「反復ごとに有効な配列インデックスの範囲全体から常に j を選択する」を検索してください)、ここに投稿された他の実装の何が問題なのかについての議論を参照してください。)

using System;
using System.Collections.Generic;

namespace ConsoleApplication2
{
    static class Program
    {
        static void Main(string[] args)
        {
            Shuffler shuffler = new Shuffler();
            List<int> list = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            shuffler.Shuffle(list);

            foreach (int value in list)
            {
                Console.WriteLine(value);
            }
        }
    }

    /// <summary>Used to shuffle collections.</summary>

    public class Shuffler
    {
        public Shuffler()
        {
            _rng = new Random();
        }

        /// <summary>Shuffles the specified array.</summary>
        /// <typeparam name="T">The type of the array elements.</typeparam>
        /// <param name="array">The array to shuffle.</param>

        public void Shuffle<T>(IList<T> array)
        {
            for (int n = array.Count; n > 1; )
            {
                int k = _rng.Next(n);
                --n;
                T temp = array[n];
                array[n] = array[k];
                array[k] = temp;
            }
        }

        private System.Random _rng;
    }
}
于 2013-01-23T09:06:43.403 に答える
2

あなたが実際に何をしているかに応じて、次のようなことができます:

using System;
using System.Collections.Generic;
using System.Linq;

namespace SO14473321
{
    class Program
    {
        static void Main()
        {
            UniqueRandom u = new UniqueRandom(Enumerable.Range(1,10));
            for (int i = 0; i < 10; i++)
            {
                Console.Write("{0} ",u.Next());
            }
        }
    }

    class UniqueRandom
    {
        private readonly List<int> _currentList;
        private readonly Random _random = new Random();

        public UniqueRandom(IEnumerable<int> seed)
        {
            _currentList = new List<int>(seed);
        }

        public int Next()
        {
            if (_currentList.Count == 0)
            {
                throw new ApplicationException("No more numbers");
            }

            int i = _random.Next(_currentList.Count);
            int result = _currentList[i];
            _currentList.RemoveAt(i);
            return result;
        }
    }
}
于 2013-01-23T06:42:20.783 に答える
-1

0 から 9 までの一意の乱数

      int sum = 0;
        int[] hue = new int[10];
        for (int i = 0; i < 10; i++)
        {

            int m;
            do
            {
                m = rand.Next(0, 10);
            } while (hue.Contains(m) && sum != 45);
            if (!hue.Contains(m))
            {
                hue[i] = m;
                sum = sum + m;
            }

        }
于 2020-07-03T14:12:58.640 に答える