1

I have following code written in c#.In which I am printing permutation of string.

void Main()
{
    RecPermute("", "abc");

}



void RecPermute(string soFar, string rest) {
    if (rest == "") {
        soFar.Dump();
    } else {
        for(int i=0; i<rest.Length; i++) {
            string next = soFar + rest[i];
            string remaining = rest.Substring(0, i) + rest.Substring(i+1);
            RecPermute(next, remaining);
    }
    }
}

Now I change the signature of method as below.

List<string> RecPermute(string soFar, string rest) 

and change the code

List<string> RecPermute(string soFar, string rest) {
List<string> result=new List<string>();
    if (rest == "") {
        //soFar.Dump();
        result.Add(soFar);
    } else {
        for(int i=0; i<rest.Length; i++) {
            string next = soFar + rest[i];
            string remaining = rest.Substring(0, i) + rest.Substring(i+1);
            RecPermute(next, remaining);
    }
    }
    return result;
}

The problem is that I am not getting any result.

0

1 Answer 1

1

You have List<string> result=new List<string>(); as local variable. This is what you want

List<string> result=new List<string>(); // NOT LOCAL!!!
List<string> RecPermute(string soFar, string rest) {

    if (rest == "") {
        //soFar.Dump();
        result.Add(soFar);
    } else {
        for(int i=0; i<rest.Length; i++) {
            string next = soFar + rest[i];
            string remaining = rest.Substring(0, i) + rest.Substring(i+1);
            RecPermute(next, remaining);
    }
    }
    return result;
}

Please, not that using a class level variable to store the result is most likely a bad idea. I used this only as an example to point out that when result is local - it does not get populated with data.

Read the comments for this answer - there are different solutions for this problem, my personal favorite is to use a parameter:

    private List<string> RecPermute(string soFar, string rest, List<string> tmp = null)
    {
        if (tmp == null) tmp = new List<string>();
        if (rest == "")
        {
            //soFar.Dump();
            tmp.Add(soFar);
        }
        else
        {
            for (int i = 0; i < rest.Length; i++)
            {
                string next = soFar + rest[i];
                string remaining = rest.Substring(0, i) + rest.Substring(i + 1);
                RecPermute(next, remaining, tmp);
            }
        }
        return tmp;
    }
Sign up to request clarification or add additional context in comments.

11 Comments

or change to result.AddRange(RecPermute(next, remaining));
@Grundy Your solution also works (dotnetfiddle.net/w0AqFN), but in this case a lot of temporary lists are created. If this is supposed to be static implementation - a new parameter can be added - this is still cheaper in terms of memory than creating several lists (like this - dotnetfiddle.net/IaEfse)
Using a global variable as a temporary variable for a function result is bad. This function should be rewritten to be recursive. So we should return something from the else block too. Then we won't need a global variable. I wanted to do it, but I couldn't do it right away, and unfortunately, I don't have time for it now :(
@FreeNickname Why? If you have an class with the logic and getting permutations is only one step of the algorithm - getting a private field to contain the result is exactly what you need to do! This will remove the pressure from passing parameters to all the methods that implement algorithm's steps.
@DarkWalker:After making changes code is working fine.I have one question what is general rule for handling this thing in recursion
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.