#include #include #include #include #include #include #include #include #include using namespace std; class NChooseK { public: vector items; vector team; void GenNCK(size_t index, size_t nitems); }; /* This is our workhorse recursive method. It says: You may have already generated part of a team. I need nitems more team members from the strings in items, starting at index. */ void NChooseK::GenNCK(size_t index, size_t nitems) { size_t i; /* Base case -- if there are no more items to add, print out the team and return */ if (nitems == 0) { cout << team[0]; for (i = 1; i < team.size(); i++) cout << " " << team[i]; cout << endl; return; } /* This is a second base case -- if there are fewer items left to add than there are places left on the team, then it's impossible to finish, so simply return. Ask yourself why this is better than testing whether index is equal to items.size(), and returning if so. */ if (nitems > items.size() - index) return; /* Now, put the string in items[index] onto the team, and call GenNCK() recursively. Afterwards, take the string off of the team. */ team.push_back(items[index]); GenNCK(index+1, nitems-1); team.pop_back(); /* Finally, call GenNCK() recursively without putting items[index] on the team. */ GenNCK(index+1, nitems); } int main(int argc, char **argv) { NChooseK P; string s; char buf[100]; int i, n, k, len; try { if (argc != 3) throw "usage: n_choose_k n k"; if (sscanf(argv[1], "%d", &n) != 1) throw "usage: n_choose_k n k - n must be an integer."; if (sscanf(argv[2], "%d", &k) != 1) throw "usage: n_choose_k n k - k must be an integer."; if (n < 1 || k < 0) throw "usage: n_choose_k n k - n must be > 0 and k must be >= 0."; if (k > n) throw "usage: n_choose_k n k - n must be greater than or equal to k."; } catch (const char *s) { cerr << s << endl; return 1; } /* When n is <= 26, your items are uppercase characters. */ if (n <= 26) { for (i = 0; i < n; i++) { s.clear(); s.push_back('A'+i); P.items.push_back(s); } /* Otherwise, your items are numbers from 0 to n-1 (as strings). */ } else { snprintf(buf, 100, "%d", n-1); len = strlen(buf); for (i = 0; i < n; i++) { snprintf(buf, 100, "%0*d", len, i); s = buf; P.items.push_back(s); } } /* Here's the main call -- generate teams of k items using all of the strings in the "items" vector. */ P.GenNCK(0, k); }