4

I am trying write a recursive function(it must be recursive) to print out the partitions and number of partitions for 1 to n-1. For example, 4 combinations that sum to 4:

1 1 1 1
1 1 2
1 3
2 2

I am just having much trouble with the function. This function below doesn't work. Can someone help me please?

 int partition(int n, int max)
{

  if(n==1||max==1)
    return(1);
  int counter = 0;
  if(n<=max)
    counter=1;
  for(int i = 0; n>i; i++){
          n=n-1;
          cout << n << "+"<< i <<"\n";
          counter++;
          partition(n,i);         
        }

  return(counter);
}
  • "This function below doesn't work" - what *does* it do? What *does* it output with *provided* sample input? And do you understand *why* it does so or have *any* suspicions why it doesn't seem to work? – WhozCraig Mar 06 '15 at 03:07
  • max is n-1. The output it: Please enter the number: 4 3+0 2+0 1+0 1+1 2+1 counter: 2 @WhozCraig – CSCI_newbie Mar 06 '15 at 03:15
  • So, given a number N you want to find all the **unique** sets of natural numbers each in the range [1, N) that sum up to N in a recursive manner? – jschultz410 Mar 06 '15 at 03:59
  • yes, but in the range of 1 to n-1 – CSCI_newbie Mar 06 '15 at 04:13
  • @CSCI_newbie I figured out a solution. It wasn't all that easy. Here are some hints: have your recursive function take N, the current sum, the current array of summands and the number of summands. The base case of the recursion is when sum == N. In that case simply print the array and return. See if you can figure out the recursive case. It might be easier to recursively print out all the permutations of the sum first and then figure out how to reduce it to only the unique sets of summands. – jschultz410 Mar 06 '15 at 05:14

2 Answers2

1

Here's a good start on your problem:

#include <stdlib.h>
#include <stdio.h>

void partition(int n, int sum, int *summands, int num_summands)
{
  int i;

  if (sum == n)  // base case of recursion
  {
    if (num_summands > 1)  // don't print n by itself
    {
      for (i = 0; i < num_summands; ++i)
        printf("%d ", summands[i]);

      printf("\n");
    }
  }
  else
  {
    /* TODO: fill in recursive case */
    /* Iteratively recurse after appending one additional, varying summand to summands */
    /* It might be easier to first generate all permutations of the sums */
    /* and then figure out how to reduce that down to only the unique sets of summands (think sorting) */
  }
}

int main(int argc, char **argv)
{
  if (argc == 1)
  {
    printf("usage: %s <num>; where num > 1\n", argv[0]);
    return 1;
  }

  int n = atoi(argv[1]);

  if (n <= 1)
  {
    printf("usage: %s <num>; where num > 1\n", argv[0]);
    return 1;
  }

  int summands[n+1];               // NOTE: +1's are to make summands[-1] always safe inside recursion

  summands[0] = 1;                 // NOTE: make summands[-1] == 1 at top level of recursion
  partition(n, 0, summands+1, 0);  // NOTE: +1's are to make summands[-1] always safe inside recursion

  return 0;
}

If you need a count of the sums you find, then you can add an extra parameter to partition that is a pointer to (int) a count of the sums found so far. You'd only increment that count in your printing base case. In main, you'd pass a pointer to a zero initialized integer and in the recursion you'd just pass the pointer along. When you get back to main you can print the number of sums you found.

jschultz410
  • 2,849
  • 14
  • 22
0

This is a simple pseudocode , see if you understand , initial call is with recPartition(n,1)

int A[100]
int n
int cnt = 0
recPartition(int remaining,int indx)
    if(remaining <0 )
       return
    if(remaining == 0)
        print from 1 to indx in A
        ++cnt
        return
    for i from 1 to remaining
         if(i!=n)
             A[indx] = i
             recPartition(remaining-i,indx+1) 
Tamim Addari
  • 7,591
  • 9
  • 40
  • 59