I'm trying to print out all possibilities of nCr, which are the combinations when order doesn't matter. So 5C1 there are 5 possibilities: 1 , 2, 3, 4, 5. 5C2 there are 10 possibilities: 1 2, 1 3, 1 4, 1 5, 2 3, 2 4, 2 5, 3 4, 3 5, 4 5.
I made functions that print what I want for r = 2, r = 3, and r = 4, and I sort of see the pattern, but I cant seem to make a working method for variable r:
public void printCombinationsChoose2(int n, int k) //for when k = 2
{
for (int a = 1; a < n; a++)
{
for (int b = a + 1; b <= n; b++)
{
System.out.println("" + a + " " + b);
}
}
}
public void printCombinationsChoose3(int n, int k) //for when k = 3
{
for (int a = 1; a < n - 1; a++)
{
for (int b = a + 1; b < n; b++)
{
for (int c = b + 1; c <= n; c++)
{
System.out.println("" + a + " " + b + " " + c);
}
}
}
}
public void printCombinationsChoose4(int n, int k) //for when k = 4
{
for (int a = 1; a < n - 2; a++)
{
for (int b = a + 1; b < n - 1; b++)
{
for (int c = b + 1; c < n; c++)
{
for (int d = c + 1; d <= n; d++)
{
System.out.println("" + a + " " + b + " " + c + " " + d);
}
}
}
}
}
public void printCombinations(int n, int k) //Doesn't work
{
int[] nums = new int[k];
for (int i = 1; i <= nums.length; i++)
nums[i - 1] = i;
int count = 1;
while (count <= k)
{
for (int a = nums[k - count]; a <= n; a++)
{
nums[k - count] = a;
for (int i = 0; i < nums.length; i++)
System.out.print("" + nums[i] + " ");
System.out.println();
}
count++;
}
}
So I think the layout of my last method is right, but I'm just not doing the right things, because when I call printCominbations(5, 2)
, it prints
1 2
1 3
1 4
1 5
1 5
2 5
3 5
4 5
5 5
when it should be what I said earlier for 5C2.
Edit
The last example was bad. This is a better one to illustrate what it's doing wrong: printCombinations(5, 3)
gives this:
1 2 3
1 2 4
1 2 5
1 2 5
1 3 5
1 4 5
1 5 5
1 5 5
2 5 5
3 5 5
4 5 5
5 5 5
How do I get it to be:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
How about this:
public class Test {
public static void main(final String[] args) {
print_nCr(7, 4);
}
public static final void print_nCr(final int n, final int r) {
int[] res = new int[r];
for (int i = 0; i < res.length; i++) {
res[i] = i + 1;
}
boolean done = false;
while (!done) {
System.out.println(Arrays.toString(res));
done = getNext(res, n, r);
}
}
/////////
public static final boolean getNext(final int[] num, final int n, final int r) {
int target = r - 1;
num[target]++;
if (num[target] > ((n - (r - target)) + 1)) {
// Carry the One
while (num[target] > ((n - (r - target)))) {
target--;
if (target < 0) {
break;
}
}
if (target < 0) {
return true;
}
num[target]++;
for (int i = target + 1; i < num.length; i++) {
num[i] = num[i - 1] + 1;
}
}
return false;
}
}
The key to this solution for me was to look at the problem as a numbering system and you want to increase a number by one and every time you reach an upper bound, you just carry the excess to the left one and ... You just need to implement the increasing algorithm correctly...