手动终止递归

时间:2015-05-04 10:07:02

标签: c# recursion

我已经编写了一个递归(实际上我发现了在线递归)以获得一组数字的所有可能的排列,但在某些情况下,由于大量可能的排列,我想添加一个If语句来终止在它经历所有排列之前的递归。我已经尝试输入一个返回声明,但它似乎没有用。

我在编码方面有点新手,如果答案对每个人都很明显,那我就道歉了。我只是无法得到它。

class EntryPoint
{        
    static void Main()
    {           
        //input an initial sequence of the trains to schedule
        Console.Write("Input train permutation");
        string inputLine = Console.ReadLine();

        GenerateTrainOrder GTO = new GenerateTrainOrder();
        GTO.InputSet = GTO.MakeCharArray(inputLine);
        GTO.CalcPermutation(0);
    }
}


class GenerateTrainOrder
{
    private int elementLevel = -1; // elements examined iterates immediately after the CalcPermutation initiates so we must set it equal -1 to start from 0
    private int[] permutationValue = new int[0];

    public int[,] Paths = new int[ParametersClass.timetableNumber, ParametersClass.trainsToSchedule];

    private char[] inputSet;
    public char[] InputSet
    {
        get { return inputSet; }
        set { inputSet = value; }
    }

    private int permutationCount = 0;
    public int PermutationCount
    {
        get { return permutationCount; }
        set { permutationCount = value; }
    }

    //transform the input from the console to an array for later use
    public char[] MakeCharArray(string InputString)
    {
        char[] charString = InputString.ToCharArray();
        Array.Resize(ref permutationValue, charString.Length);

        return charString;
    }

    public void CalcPermutation(int k)
    {            
            elementLevel++;
            permutationValue.SetValue(elementLevel, k);

            //if we have gone through all the elements which exist in the set, output the results
            if (elementLevel == ParametersClass.trainsToSchedule)
            {
                OutputPermutation(permutationValue); // output TrainOrder by passing the array with the permutation 
            }

            //if there are elements which have not been allocated a place yet
            else
            {
                for (int i = 0; i < ParametersClass.trainsToSchedule; i++)
                {
                    //iterate until we come upon a slot in the array which has not been allocated an elements yet
                    if (permutationValue[i] == 0)
                    {

                        CalcPermutation(i); //rerun the code to allocate an element to the empty slot. the location of the empty slot is given as a parameter (this is how k increments)

                    }  
                }
            }

            elementLevel--;
            permutationValue.SetValue(0, k);
    }

    private void OutputPermutation(int[] value)
    {
        int slot = 0;

        foreach (int i in value)
        {
            Paths[permutationCount, slot] = Convert.ToInt16(Convert.ToString(inputSet.GetValue(i-1)));

            slot++;
        }

        PermutationCount++;
    }
}

3 个答案:

答案 0 :(得分:0)

停止递归计算有点棘手。最好的方法涉及全局变量(如果有对象,则包含私有类变量)。

此变量表示递归是否应该停止:

bool stopRecursion = false;

现在,在计算中,您将在每个步骤后更新此变量:

if(_my_condition_is_met) stopRecursion = true;

在递归调用方法的开头,检查此变量的状态:

public void CalcPermutation(int k)
{  
    if(stopRecursion) return;
    ...

每次调用CalcPermutation后都会检查此变量:

for (int i = 0; i < ParametersClass.trainsToSchedule; i++)
{
    //iterate until we come upon a slot in the array which has not been allocated an elements yet
    if (permutationValue[i] == 0)
    {
        CalcPermutation(i);
        if(stopRecursion) return;
        ....

使用此方法,只要符合停止条件,就可以展开甚至深度调用级别。

答案 1 :(得分:0)

感谢大家的回复。我设法通过以下方式使其发挥作用:

在CalcPermutation(i)行下,我写了

if (permutationCount == ParametersClass.timetableNumber)
{
       return;
}

我尝试使用不同的输入运行它几次,它似乎工作正常。

答案 2 :(得分:-1)

for (int i = 0; i < ParametersClass.trainsToSchedule; i++)
            {
                //iterate until we come upon a slot in the array which has not been allocated an elements yet
                if({your condition}){
                  break;
                }
                if (permutationValue[i] == 0)
                {

                    CalcPermutation(i); //rerun the code to allocate an element to the empty slot. the location of the empty slot is given as a parameter (this is how k increments)

                }  
            }