如何生成不同数字的所有数字(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);
}
}
}
}
好的,正确观察,有(n-1)!数组的不同排列,你想要一个以随机顺序列出它们的算法。如果你需要以随机顺序生成整个列表,我建议先生成排列列表,然后再进行混洗。如果你只是想一次生成这些,并且不介意重复,我建议采取任何固定的排列,洗牌有资格改变的数字,然后输出结果。这些都在概念上很简单;使用Fisher-Yates进行改组。
相反,假设您要做的是生成一系列排列,所有排列都是不同的,而不首先计算所有排列的列表。这样的清单对于合理的n来说会很长。如果你的序列的长度相对于排列的数量(n-1)!来说很小,那么记住你已经生成了哪些并且一遍又一遍地尝试直到你得到一个不在列表中的那个是一种非常可行的方法。您需要弄清楚所涉及的概率,以便您了解“小”对您来说意味着什么(随着每个新排列添加到列表中,预期的运行时间会变得更糟)。如果已知排列的数量是所有可能排列的数量的相当大的一部分,则可能更好地提前计算它们,可能以压缩格式计算以节省空间。
正如你所说的“不同的数字”,我认为它是一种“独特的结果”类型的约束(即,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位)括起来的数字作为单独的事物 - 可能是自定义类中的自己的字段 - 可能有助于此。