嗨,大家好我试图学习排列和恢复。我正在寻找一种方法,我可以在同一时间使用。
MAIN:
namespace Recursive_Permutation
{
class Program
{
static void Main(string[] args)
{
int[] array = new int[5] { 0, 0, 0, 0, 0 };
CalPermutations CP = new CalPermutations();
CP.Run(array, array.Length-1);
}
}
}
这是我的简单代码:
namespace Recursive_Permutation
{
public class CalPermutations
{
public int Run(int[] array,int indexer)
{
if (indexer > array.Length)
{
return 1;
}
else
{
for (int i = 0; i <= array.Length; i++)
{
array[indexer] = i;
Display(array);
}
Run(array, indexer-1);
}
return indexer;
}
public void Display(int[] array)
{
foreach (int num in array)
{
Console.Write(num);
}
Console.WriteLine();
}
}
}
以下是该计划的输出:
问题: 它可能对其他人来说很简单,但我现在很难混淆它如何操纵它仍然计算第一个数字(位置[0])1到5并进入下一个位置和(位置1)并添加1并返回[0]并再次开始计数,直至达到5。
我希望我的解释是可以理解的...... thx。
答案 0 :(得分:0)
更新:根据评论为每种方法添加评论。
public class Program
{
public static void Main(string[] args)
{
int[] array = new int[] { 0, 0, 0, 0, 0};
CalPermutations CP = new CalPermutations();
CP.Run(array, 0);
}
}
public class CalPermutations
{
// Prints all the permutations of array, starting at the specified index.
public void Run(int[] array, int indexer)
{
if (indexer < 0 || indexer >= array.Length)
return;
// Keep [0, indexer] combination constant, change combination on right i.e. (indexer, Array.length).
Run(array, indexer+1);
// All the elements on right have finished, increment current element.
array[indexer]++;
// Check if current combination is STILL valid.
if(array[indexer] <= array.Length)
{
// since current combination is still valid, display it, and execute the process again on the new combination.
Display(array);
Run(array, indexer);
}
else
{
// Since current element is out of range, reset it.
array[indexer] = 1;
}
}
// Prints all the elements in array.
public void Display(int[] array)
{
foreach (int num in array)
Console.Write(num);
Console.WriteLine();
}
}
答案 1 :(得分:0)
我把这个更简单的使用递归和置换的例子放在一起。它在内部使用字符串,但产生相同的结果。
它仅用于概念验证,因为在专业环境中没有人会为这些简单的东西递归。递归可能会产生很大的内存影响,但会以一种简单的方式描述一些问题。
如果我必须在迭代和递归解决方案之间做出选择,我会在大多数情况下采用迭代解决方案。
// Main entrance
public void DoStuff()
{
// define variations
List<string> possibilities = new List<string>() { "0", "1", "2", "3", "4", "5" };
// resultlist, will be filled later
List<string> permutations = new List<string>();
// how many values will be taken from the possibilities
int digits = 5;
//do the work
Permute(permutations, possibilities, digits, "");
// display the work
foreach (var item in permutations)
{
Console.WriteLine(item);
}
}
/// <summary>
/// generates a List of permuted strings
/// </summary>
/// <param name="permutations">resultlist</param>
/// <param name="possibilities">possible values of the digit</param>
/// <param name="digitsLeft">how many digits shall be appended</param>
/// <param name="current">the current value of the unfinished result</param>
private void Permute(List<string> permutations, List<string> possibilities, int digitsLeft, string current)
{
// uncomment to see how it works in detail
//Console.WriteLine("step:"+current);
// most important: define Stop conditions for the recursion
// safety stop
if (digitsLeft < 0)
{// end of digits :), normally we never end up here
return;
}
// normal stop
if (digitsLeft == 0)
{// normal endpoint, add the found permutation to the resultlist
permutations.Add(current);
return;
}
// now prepare the recursion, try each possibility
foreach (var item in possibilities)
{
// digitsLeft need to be decreased, since we add a concrete digit to the current value (current+item)
// important: (current + item) generates a new string in memory, the old values won't be touched, permutations possibilities are references, so no memory impact here
Permute(permutations, possibilities, digitsLeft - 1, current + item);
}
}