Home > Software engineering >  How can I perform recursive methods with generic class
How can I perform recursive methods with generic class

Time:07-06

I have a class that has one function that does multiplication without using build-in methods. I got my function to work without using a generic, but I can get it to work while using a generic. My problem is my recursive call-back function is giving me an error each time I try and call it. Any feedback?

my error is : Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ff7bc42af70)

class Math5<T: Numeric> {
    func multiplier(_ a: T, _ b: T) -> T {
        if a == 0 || b == 0 {
            return 0;
        } else {
            return a   multiplier(a, b - 1)
        }
    }
}

CodePudding user response:

Your multiplication algorithm is only valid if b is a non-negative integer. If b is negative, or includes a fraction, then b == 0 will never become true. If you should at least constrain type T to UnsignedInteger, thin the compiler will enforce those limitations at compile-time:

class Math5<T: UnsignedInteger> {

You can generalize so that the first argument can be any AdditiveArithmetic while only allowing an UnsignedInteger for the second argument. Let's drop the class and use a free function:

func multiply<LHS: AdditiveArithmetic, RHS: UnsignedInteger>(
    _ lhs: LHS,
    _ rhs: RHS
) -> LHS {
    guard lhs != .zero && rhs != 0 else { return .zero }
    return lhs   multiply(lhs, rhs - 1)
}

multiply(2.5, 3 as UInt) // result: 7.5

You can still crash with a stack overflow if you pass in a large enough value for b. Since Swift doesn't guarantee tail call elimination, you should also change your algorithm to use a loop instead of recursion if you want to avoid stack overflows.

func multiply<LHS: AdditiveArithmetic, RHS: UnsignedInteger>(
    _ lhs: LHS,
    _ rhs: RHS
) -> LHS {
    guard lhs != .zero else { return .zero }
    var answer: LHS = .zero
    var rhs = rhs
    while rhs > 0 {
        answer  = lhs
    }
    return answer
}

CodePudding user response:

Make the function generic

func multiplier<T: Numeric>(_ a:T, _ b:T) -> T {
 if a == 0 || b == 0 {
  return 0
 }
 return a multiplier(a,b-1)
}

Same implementation

  • Related