Writing a recursive function by using optional parameters

In summary, the first way of writing recursive functions with an optional parameter can be fancier and slightly shorter, but also has the disadvantage of potentially violating OOP principles and adding an unnecessary conditional check in each iteration. The second way is cleaner, clearer, and more efficient, and it is recommended to separate the public and private parts of the code. It is also suggested to use a nullable int as the optional parameter instead of a specific value like -1.
  • #1
SlurrerOfSpeech
141
11
One way that I often write recursive functions in my work is by having an optional parameter that is used for all calls after the first. For example, here's how I might implement the classic "Find the largest palindrome in a given string" interview-type problem:

Code:
using System;

public static class Extensions
{
    private static string Reverse(this string s)
    {
        char[] charArray = s.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }   
   
    public static string LargestPalindrome(this string s, int k = -1)
    {
        if(k == -1) // If function was called for the first time
        {
            return s.LargestPalindrome(s.Length);           
        }

        // Try to find palindrome in all substrings of length k
        for(int i = 0, j = s.Length - k; i <= j; ++i)
        {
            string ss = s.Substring(i, k);
            if(ss == ss.Reverse())
                return ss;           
        }
       
        // If here, didn't find a palindrome. Try all substrings
        // of length k - 1.
        return s.LargestPalindrome(k - 1);
       
    }
}

                   
public class Program
{   
    public static void Main()
    {
        string s = "kandasndddsk"; 
        Console.WriteLine(s.LargestPalindrome()); // Expected output: "ddd" 
    }
}

This is an alternative to writing it like

Code:
using System;

public static class Extensions
{
    private static string Reverse(this string s)
    {
        char[] charArray = s.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }   
   
    private static string LargetsPalindrome_Subroutine(this string s, int k)
    {
        // Try to find palindrome in all substrings of length k
        for(int i = 0, j = s.Length - k; i <= j; ++i)
        {
            string ss = s.Substring(i, k);
            if(ss == ss.Reverse())
                return ss;           
        }
       
        // If here, didn't find a palindrome. Try all substrings
        // of length k - 1.
        return s.LargestPalindrome(k - 1);       
    }
   
    public static string LargestPalindrome(this string s)
    {
        return s.LargestPalindrome(s.Length);                   
    }
}

                   
public class Program
{   
    public static void Main()
    {
        string s = "kandasndddsk"; 
        Console.WriteLine(s.LargestPalindrome()); // Expected output: "ddd" 
    }
}

Let me explain what I think are the advantages and disadvantages of the first way.

Advantages:
* Fancier
* Slightly less code

Disadvantages:
* Although its intent is for the caller to use it with empty pamarameters, the call with a parameter is public and so it can be used as not intended. It could be argued that this violates OOP religious commandements.
 
Technology news on Phys.org
  • #2
Personally I would in general fancy the second version and possibly with the recursive function non-public as you have made it unless it really was meant to be called by an unknown caller. In your case the recursive function is simple and it may make sense for a caller to specify the maximum palindrome length, but in other cases where delicate data structures have to be prepared first you would not want to leave that up to an unknown caller.

Also, in this particular case (and since its already on tail recursive form) I think I would write the algorithm as a single non-recursive function, possibly still with an optional argument where the caller can specify maximum palindrome length.

Later: I suppose this is just an example and you are aware that the comparison with the reverse string can be done without allocating a new string.
 
  • #3
I would disagree with both of the claimed Advantages.

1. "Fancier". This is simply not an advantage. In what way is "fancy" code better? If anything, "fancier" code can lead to bugs as usage of it can be obscure (as implied in the Disadvantages).

2. "Slightly less code". While the first version does away with one method definition, the equivalent call is still made, and the (doesn't always mean much) measure "lines of code" is about the same.

Worse, an entire conditional is added - that has to be evaluated in every iteration. The "if (k == -1)" is tested every time the recursed method is called ... and the condition it looks for only applies once. It might not matter in this simple example, but in general a recursed or iterated method should be as lean as possible.

So I'd prefer the second method. It's cleaner, clearer and more efficient.

Even if I wanted callers to be able to specify the maximum length of palindrome, I'd have the public and private parts separated. The public method would be able to do validation (like checking the requested length isn't longer than the string itself), before calling the private method to do the work.

Finally, and maybe this is more an issue of style, I'd use a nullable int as the optional parameter. Using "-1" as a guard feels a bit old fashioned, and -1 vs value is less obvious than null vs value. (The inner routine would still take a non-nullable int).
 

1. What is a recursive function?

A recursive function is a function that calls itself repeatedly until a base condition is met. It is a technique used in programming to solve problems that can be broken down into smaller, simpler versions of the same problem.

2. How do optional parameters work in a recursive function?

Optional parameters in a recursive function are used to provide a default value for a parameter if no value is passed when the function is called. This helps to make the function more flexible and adaptable to different situations.

3. Can a recursive function have more than one optional parameter?

Yes, a recursive function can have multiple optional parameters. This allows for even more flexibility in the function and allows it to handle a wider range of scenarios.

4. What is the purpose of using optional parameters in a recursive function?

The purpose of using optional parameters in a recursive function is to make the function more versatile and able to handle a variety of input values. It also helps to make the code more concise and easier to read.

5. Are there any limitations to using optional parameters in a recursive function?

One limitation of using optional parameters in a recursive function is that it can make the code more complex and potentially harder to debug. It is important to use them carefully and only when necessary to avoid confusion or errors.

Similar threads

  • Programming and Computer Science
2
Replies
55
Views
4K
  • Programming and Computer Science
Replies
3
Views
2K
  • Programming and Computer Science
Replies
5
Views
1K
  • Programming and Computer Science
Replies
3
Views
1K
  • Programming and Computer Science
Replies
3
Views
3K
  • Programming and Computer Science
Replies
2
Views
2K
  • Programming and Computer Science
Replies
7
Views
2K
  • Programming and Computer Science
Replies
8
Views
2K
  • Programming and Computer Science
Replies
1
Views
732
  • Programming and Computer Science
Replies
17
Views
2K
Back
Top