问题
I need to write a recursive function that calculates all the possible combinations of length "n" in a list, in Python, without importing anything like itertools etc.
So what I have so far is:
if n == 0:
return [[]]
elif lst == []:
return []
else:
rest = subsets(lst[1:], n-1)
for next in lst: # Loop through something?
return lst[0] + rest #Add something?
I seem to be lacking an understanding of how the recursive calls work, can someone explain this to me?
回答1:
In the absence of the required output specifications, we could write some pseudo-code like this:
def combinations(sub, data_set, items_needed):
if you dont need, return sub
for item in data_set:
append item to sub
#pop() item from data_set?
decrease items_needed # added one more, so we need one less
combinations(new_sub, data_set, items_needed)
Where poping() or not will depend on you wanting (or not) unique items in the subset.
If you say you don't want both [a, b] and [b, a] you would have to also keep track of the index of the last item added, in order to only add new items to create new combinations.
def combinations(sub, data_set, index, still_needed):
if you dont need any, return
for i in range(index, len(data_set)):
append data_set[i] to sub
decrease still_needed
combinations(sub, data_set, index+1, still_needed)
回答2:
This sounds dangerously like a homework problem. Why does it have to be recursive, as that just seems bad.
Regardless, recursively what you are doing is going through every element in the list and then appending that to the beginning of every other combination of length n - 1. So, if your list was [1, 2, 3], you are wanting an algorithm where the call stack will look like:
foo([], [1, 2, 3], n) ==
foo([1], [2, 3], n - 1) +
foo([2], [1, 3], n - 1) +
foo([3], [1, 2], n - 1)
Where,
foo([1], [2, 3], n - 1) ==
foo([1, 2], [3], n - 2) +
foo([1, 3], [2], n - 2)
etc...
You can terminate the recursive calls whenever you have n == 0, or the middle list is empty. And you just return the first argument.
This all make sense? (I can code it up, if desired. I think if you look at the desired callstacks, it should mostly put itself together.)
回答3:
A useful trick when faced with such a basic question (one that is frequently used as introductory level homework or in some programming interviews) is to look at RosetteCode (From which you, too, can learn to impress your friends with words like "chrestomathy"). For this one, in particular we find:
#/usr/bin/env python
# From: http://rosettacode.org/wiki/Combinations#Python
def comb(m, lst):
if m == 0:
return [[]]
else:
return [[x] + suffix for i, x in enumerate(lst)
for suffix in comb(m - 1, lst[i + 1:])]
... along with implementations in dozens of other languages for comparison.
Another handy site is PLEAC (for the "Programming Language Examples Alike Cookbook" project) ... though it has less academic and leans towards more practical programming tasks.
来源:https://stackoverflow.com/questions/24643704/combinations-recursive-algorithm