Is it possible to remove recursion from this function?

前端 未结 3 595
忘了有多久
忘了有多久 2021-01-20 01:26

I have been playing with this a while, and just cannot see an obvious solution. I want to remove the recursion from the XinY_Go function.

def XinY_Go(x,y,ind         


        
相关标签:
3条回答
  • 2021-01-20 02:01

    Look at this code for creating all permutations, I guess I'd be relatively simple to implement something similar for your problem.

    How to generate all permutations of a list in python?

    0 讨论(0)
  • 2021-01-20 02:05

    Everything we think of as recursion can also be thought of as a stack-based problem, where the recursive function just uses the program's call stack rather than creating a separate stack. That means any recursive function can be re-written using a stack instead.

    I don't know python well enough to give you an implementation, but that should point you in the right direction. But in a nutshell, push the initial arguments for the function onto the stack and add a loop that runs as long as the size of the stack is greater than zero. Pop once per loop iteration, push every time the function currently calls itself.

    0 讨论(0)
  • 2021-01-20 02:10

    A naive implementation of @Joel Coehoorn's suggestion follows:

    def XinY_Stack(x, y):
        stack = [(x, 0, [0]*y)]
        while stack:
            x, index, slots = stack.pop()
            if (y - index) == 1:
                slots[index] = x
                print slots
                slots[index] = 0
            else:
                for i in range(x + 1):
                    slots[index] = x-i
                    stack.append((i, index + 1, slots[:]))
    

    Example:

    >>> XinY_Stack(2, 3)
    [0, 0, 2]
    [0, 1, 1]
    [0, 2, 0]
    [1, 0, 1]
    [1, 1, 0]
    [2, 0, 0]
    

    Based on itertools.product

    def XinY_Product(nmarbles, nslots):
        return (slots
                for slots in product(xrange(nmarbles + 1), repeat=nslots)
                if sum(slots) == nmarbles) 
    

    Based on nested loops

    def XinY_Iter(nmarbles, nslots):
        assert 0 < nslots < 22 # 22 -> too many statically nested blocks
        if nslots == 1: return iter([nmarbles])
        # generate code for iter solution
        TAB = "  "
        loopvars   = []
        stmt       = ["def f(n):\n"]
        for i in range(nslots - 1):
            var = "m%d" % i
            stmt += [TAB * (i + 1), "for %s in xrange(n - (%s)):\n"
                     % (var, '+'.join(loopvars) or 0)]
            loopvars.append(var)
    
        stmt += [TAB * (i + 2), "yield ", ','.join(loopvars),
                 ', n - 1 - (', '+'.join(loopvars), ')\n']
        print ''.join(stmt)
        # exec the code within empty namespace
        ns = {}
        exec(''.join(stmt), ns, ns)
        return ns['f'](nmarbles + 1) 
    

    Example:

    >>> list(XinY_Product(2, 3))
    [(0, 0, 2), (0, 1, 1), (0, 2, 0), (1, 0, 1), (1, 1, 0), (2, 0, 0)]
    >>> list(XinY_Iter(2, 3))
    def f(n):
      for m0 in xrange(n - (0)):
        for m1 in xrange(n - (m0)):
          yield m0,m1, n - 1 - (m0+m1)
    
    [(0, 0, 2), (0, 1, 1), (0, 2, 0), (1, 0, 1), (1, 1, 0), (2, 0, 0)]
    
    0 讨论(0)
提交回复
热议问题