-1

I have seen people struggling to write an effective recursive function. Almost certainly, people don't get the recursive function working right at the first attempt.

This post will help the developers understand what actually needs to be done to write a proper recursive function. Also, get it right at the first attempt.

Please see the Answer below:

jscs
  • 63,694
  • 13
  • 151
  • 195
Deepak Badiger
  • 448
  • 7
  • 18
  • 5
    This is not a Question. (And frankly, even as an attempt to educate, I don't think this is particularly useful or helpful.) – Stephen C Oct 05 '14 at 07:05

2 Answers2

0

Speaking really generally, one way of thinking about recursive functions is to go through three steps each time:

  1. Identify the base case
    • this is when you know to stop recursing
    • it is normally the simplest possible input to your function
  2. Write a step case which will enable your function to eventually terminate
    • don't worry about the result yet
    • focus on making your input a bit 'smaller' in the relevant sense (a smaller number, a shorter array etc)
  3. Modify the step case so that the correct result is returned
    • in other words, perform a unit of work

Take the example of working out the digits of a number. This can be done using tail recursion, which is one common kind of recursion.

With the above formulation:

  1. our base case is a single digit number;
  2. our step case needs to recurse using a number with less digits; and
  3. we need to make sure that we actually are building up an array of digits each time.

And so if we were to implement this in Swift, we'd end up with a conceptually simple result:

extension Int {
    func digitsInBase(base: Int) -> [Int] {
        /*
         * Check for the 'base case', ie the simplest input
         * We can immediately deal with this situation
         */
        if self < base {
            return [self]
        }

        /*
         * Here, we have the 'step case'
         * The idea is to break the problem into small parts, while
         * making sure we get a bit closer to the base case each time
         */
        return (self/base).digitsInBase(base) + [self%base]
    }

    // convenience property for a common base
    var digits: [Int] {
        return self.digitsInBase(10)
    }
}

123.digits // [1, 2, 3]
7.digitsInBase(2) // [1, 1, 1]

There's nothing conceptually more difficult to extending this to something like a loop, as the other answer does, but it's a mistake to think that all recursion involves loops.

To take the other answer's example of recursively summing a sequence, we make a base/step decision on each element:

  1. the base case is an element which can be converted to a floating point number;
  2. the step case is an element which is a sequence; and
  3. we need to add to our result either the element itself, or the recursive sum of its elements, each time.
sapi
  • 9,944
  • 8
  • 41
  • 71
-1

What is Recursive Function?
Recursive function is a block of code that calls itself again and again until the break condition is satisfied.

Important aspects of Recursive Function:

  1. A looping block (E.g., for-loop)
    1.1 Write a loop that will iterate the topmost collection
    1.2 An If condition, Inside this if-condition, break the loop when the required condition is satisfied
    1.3 An else condition to call the recursive function in order to loop through the child collection
  2. A recursive function that calls itself when the break condition is not satisfied
    2.1 Write a loop that will iterate the child collection
    2.2 An If condition, Inside this if-condition, break the loop when the required condition is satisfied
    2.3 An else condition to call the self function in order to loop through the child collection

Sample Code:

import UIKit

let arr1 = [1,2,3,4,5]
let arr2 = [6,7,8,9,10]
let arr3 = [11,12,13,14,15]
let arr4 = [16,17,18,19,20]
let arr5 = [arr1, arr2, 26, 27]
let arr6 = [arr3, arr4, 28]
let arrMain = [arr5, arr6, 21, 22, 23, 24, 25]

var compareNumber:Int = 5
var foundNumber:Int = 0

func recurringFunc(numbers: NSArray) -> Void {
    for number in numbers{
        "the number is \(number)"
        if number is Int{
            if number.isEqual(compareNumber){
                foundNumber = number as Int;
                break
            }
        }

        if number is NSArray{
            "the number is \(number)"
            recurringFunc(number as NSArray)
        }
    }
}

for numbers in arrMain{

    numbers

    if  numbers is Int{
        "the number is \(numbers)"
        if numbers.isEqual(compareNumber){
            foundNumber = numbers as Int;
            break
        }
    }

    if numbers is NSArray{
        "the number is \(numbers)"
        recurringFunc(numbers as NSArray)
   }

}

foundNumber
Deepak Badiger
  • 448
  • 7
  • 18
  • 1
    I appreciate that you're trying to help, but that code isn't particularly useful. What's with the functions returning nothing and relying on global variables?! – sapi Oct 05 '14 at 07:06
  • Thanks @Sapi. This is only a sample code to demonstrate how to make a call to the recursive function and break out of it. The global variable is used to only display output in the Swift Playground environment. – Deepak Badiger Oct 05 '14 at 07:10
  • Your main loop `for numbers in arrMain{ ...}` repeats the work of the recursive function and can simply be replaced by `recurringFunc(arrMain)`. I.e. the points #1 and #2 in your recipe are the same and are usually implemented only once. – Using global variables for both input and output data is not good style and should not be done in a recipe for a "proper recursive function". – Your statement that a looping block is an important aspect of a recursive function is at least misleading. That may be correct in this particular use-case, but not generally. – Martin R Oct 05 '14 at 08:10
  • Thanks for the correction @Martin, I too realized it lately. – Deepak Badiger Oct 06 '14 at 17:34