C#递归排列是可能的吗? (初学者)

时间:2017-12-07 09:07:25

标签: c#

嗨,大家好我试图学习排列和恢复。我正在寻找一种方法,我可以在同一时间使用。

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();
        }


    }
}

以下是该计划的输出:

enter image description here

问题: 它可能对其他人来说很简单,但我现在很难混淆它如何操纵它仍然计算第一个数字(位置[0])1到5并进入下一个位置和(位置1)并添加1并返回[0]并再次开始计数,直至达到5。

我希望我的解释是可以理解的...... thx。

2 个答案:

答案 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);
    }
}