Return the cross product of a list of lists

后端 未结 4 2143
攒了一身酷
攒了一身酷 2021-01-17 09:06

Given a list of size n, Write a program that returns all possible combination of elements contained in each list.

Example:

  • List A = \"x, z\"
4条回答
  •  -上瘾入骨i
    2021-01-17 09:18

    Edit: I'm answering this in python, because, although it's currently tagged language-agnostic, python is a good, executable pseudo-pseudocode.

    If you can write the function in a form that is Tail-recursive, i.e. in a form that looks like def f(x): return f(g(x)), it's easy to turn it into an iterative form. Unfortunately, you usually won't end up with a tail-recursive call, so you need to know a couple of tricks.

    First of all, let's say we have a function that looks like this:

    def my_map(func, my_list):
        if not my_list:
            return []
    
        return [func(my_list[0])] + change_my_list(my_list[1:])
    

    Ok, so it's recursive, but not tail recursive: it's really

    def my_map(func, my_list):
        if not my_list:
            return []
    
        result = [func(my_list[0])] + change_my_list(my_list[1:])
        return result
    

    Instead, we need to adjust the function slightly, adding what is traditionally known as an accumulator:

    def my_map(func, my_list, acc = [])
        if not my_list: return acc
        acc = acc + func(my_list[0])
        return my_map(func, my_list[1:], acc + func(my_list[0]))
    

    Now, we have a truly tail-recursive function: we've gone from def f(x): return g(f(x)) to def f(x): return f(g(x))

    Now, it's quite simple to turn that function into a non-recursive form:

    def my_map(func, my_list, acc=[]):
        while True: #added
            if not my_list: return acc
            #return my_map(func, my_list[1:], acc + func(my_list[0])) #deleted
            func, my_list, acc = func, my_list[1:], acc + func(my_list[0]) #added
    

    Now, we just tidy up a little bit:

    def my_map(func, my_list):
        acc = []
        while my_list:
            acc.append(func(my_list[0])
            my_list = my_list[1:]
    
        return acc
    

    Note you can clean it up even further using a for loop or a list comprehension, but that's left as an exercise for the reader.

    Ok, so this was a pathological example, hopefully you'd know that python has a builtin map function, but the process is the same: transform into a tail recursive form, replace the recursive call with argument reassignment, and tidy up.

    So, if you have:

    def make_products(list_of_lists):
        if not list_of_lists: return []
        first_list = list_of_lists[0]
        rest = list_of_lists[1:]
        return product_of(first_list, make_products(rest))
    

    You can convert it into a tail recursive form

    def make_products(list_of_lists, acc=[]):
        if not list_of_lists: return acc
        first_list = list_of_lists[0]
        rest = list_of_lists[1:]
        acc = product_of(acc, first_list)
        return make_products(rest, acc)
    

    Then, that simplifies to:

    def make_products(list_of_lists):
        acc=[]
        while list_of_lists: 
            first_list = list_of_lists[0]
            rest = list_of_lists[1:]
    
            acc = product_of(acc, first_list)
            list_of_lists = rest
    
        return acc
    

    Again, this can be cleaned up further, into a for loop:

    def make_products(list_of_lists):
        acc=[]
    
        for lst in list_of_lists: 
            acc = product_of(acc, lst)
    
        return acc
    

    If you've looked at the builtin functions, you might notice this is somewhat familiar: it's essentially the reduce function:

    def reduce(function, iterable, initializer):
        acc = initializer
        for x in iterable:
            acc = function(acc, x)
        return acc
    

    So, the final form is something like

    def make_products(list_of_lists):
        return reduce(product_of, list_of_lists, []) # the last argument is actually optional here
    

    You then just have to worry about writing the product_of function.

提交回复
热议问题