生成不同数字的随机数

时间:2019-02-18 17:45:01

标签: c# algorithm recursion digits

如何生成具有不同数字的所有数字(它们必须以PS开头并且具有数组的第一个数字?例如,我有数字0 1 2 3 4并且需要创建数字,例如012340、012430, 013240,0124230 ..如果我有5个数字,则意味着有24种不同的组合(!(5-1))。 这是我的代码(有点混乱,但是也许有人可以帮助我)。 也许可以通过递归来解决这个问题?

 public void GenerateDigits(int n)
    {
        n--;
        int[] numbers = new int[n];

        for (int i = 0; i < n; i++)
        {
            numbers[i] = i;
        }


        string[] allDigits = new string[n*n];
        Random rnd = new Random();
        int counter = 0;
        while (allDigits.Length != counter)
        {
            allDigits[counter] = Convert.ToString(numbers[0]) + Convert.ToString(numbers[0]);

            while (allDigits[counter].Length != n + 1)
            {
                char skc = Convert.ToChar(rnd.Next(numbers[1], numbers[n]));
                if (!allDigits[counter].Contains(skc))
                {
                    allDigits[counter] = allDigits[counter].Insert(1,1);
                }

            }

        }


        for (int i = 0; i < n; i++)
        {

        }


    }

2 个答案:

答案 0 :(得分:0)

好的,正如您正确观察到的那样,共有(n-1)个!数组的不同排列,并且需要一种以随机顺序列出它们的算法。如果您需要以随机顺序生成整个列表,建议您先生成排列列表,然后重新排列。如果您只想一次生成一个,而又不介意重复,那么我建议您采用任何固定的排列方式,将有资格更改的数字混排,然后输出结果。这些在概念上都很简单;使用Fisher-Yates进行改组。

假设您要做的是生成一个排列序列,所有排列都是不同的,而无需先计算所有排列的列表。这样的列表对于合理的n会很长。如果序列的长度相对于排列数(n-1)!很小,那么记住已经生成的排列,并一遍又一遍地尝试直到列表中没有一个,这是一种非常可行的方法。您需要计算出涉及的概率,以使您对“小”对您的含义有个好主意(随着列表中添加的每个新排列,预期的运行时间会变差)。如果已知排列的数量是所有可能排列的数量的相当大的一部分,则最好继续进行计算,最好采用压缩格式以节省空间。

答案 1 :(得分:0)

正如您所说的“不同数字”,我认为这是一种“唯一结果”约束(即,仅一次012340)。这就是我所说的“彩票问题”。

如果是这样,解决方案将是创建一个具有所有可能排列的集合,然后使用类似于以下代码的随机选择其中一些:

//Create an array. Fill it with Sequential Numbers.
int[] input = new int[20];

for(int i = 0; i < numbers.lenght; i++)
  input[i] = i;

/*Initialise the instances you will need*/
//Use the array to create a list
List<int> DrawableNumbers = new List<int>(input);
List<int> DrawnNumbers = new List<int>();

//Generate a Random Number Generator
Random rng = new Random();

/*Draw 6 from the group*/
while(DrawnNumbers.Count < 6){
  //Get a random Index to move from DrawableNumbers to DrawnNumbers
  int temp = Random.NextInt(DrawableNumbers.Count);
  DrawnNumbers.Add(DrawableNumbers[i]);
  DrawableNumbers.Remove(temp);
}

由于排列的数量是非线性的,可能需要一行很大的整数(甚至将值存储为字符串),作为高级版本,您可以仅对可能的组合进行编号。即1234是1,1243是2,依此类推,然后生成实际结果以尽可能晚地输出。

将括号中的数字(索引0的数字)作为一个单独的东西(可能是自定义类中的自己的字段)进行处理可能对此有所帮助。