Reputation: 19
I have an int array and i need to print all possible decreasing combinations which are starting with the highest number. Here's the example:
int array[MAX_LEN]={ 5 , 4 , 3 , 2 , 1 }
and the expected output:
5 , 4 , 3 , 2 , 1
5 , 4 , 3 , 2
5 , 4 , 3 , 1
5 , 4 , 2 , 1
5 , 3 , 2 , 1
5 , 2 , 1
.
.
5 , 1
.
.
5
Can someone give me an advice how to do it? Thanks
Upvotes: 0
Views: 152
Reputation: 28921
To display n things 3 at a time, you can cycle using 3 indexes:
for(i = 0; i < n-3; i++)
for(j = i+1; j < n-2; j++)
for(k=j+1; k < n-1; k++)
// display array[i], array[j], array[k]
To generalize this to display n things for k = 1 to n things at a time (this is the outer loop), with an iterative (looping non recursive) method you can use an array of indexes such as ai[n]. Then for k things at a time, you need to replace the nested loops with code that accomplishes the same thing using k indexes starting with ai[0] = 0, ai[1] = 1, ... ai[k-1] = k-1. The ranges of the indexes will be ai[0] goes from 0 to n-k, ai[1] goes from ai[0]+1 to n-k+1, ..., ai[k-1] goes from ai[k-2]+1 to n-1. The indexes are advanced like an odometer, with ai[k-1] being the least significant digit, and ai[0] being the most significant digit.
This will give you all the combinations. If they need to be in descending order, you could sort the original array or sort a copy of the original array.
The generic name for this type of function is "next combination". Example code:
#include <stdio.h>
#include <malloc.h>
int next_combination(size_t *I, size_t k, size_t n)
{
size_t i, j;
i = k-1; /* find next element to increment */
while(I[i] == (n-k+i)){
--i;
if(i == (size_t)-1){ /* if done, */
for(i = 0; i < k; i++) /* return initial combination */
I[i] = i;
return(0);
}
}
I[i] += 1; /* increment element */
for(j = i+1; j < k; j++) /* create increasing string */
I[j] = I[i]+j-i;
return(1); /* return with new combination */
}
int main(int argc, char **argv)
{
int A[5] = {5, 4, 3, 2, 1};
size_t I[5];
size_t i, k, n;
n = sizeof(A)/sizeof(A[0]); /* n things */
for(k = n; k; k--){ /* n things k at a time */
for(i = 0; i < k; i++) /* create initial combination */
I[i] = i;
do{ /* display combinations */
for(i = 0; i < k; i++)
printf("%2d", A[I[i]]);
printf("\n");
}
while(next_combination(I, k, n));
}
return(0);
}
Upvotes: 0
Reputation: 421160
This problem can be expressed as "for each subsequence of [4,3,2,1] print 5 followed by the subsequence"
To find all subsequences, you can do something along the following lines
findAllSubsequences(array) {
if (array is empty)
return an empty list
result = new list
head = array[0] // 4
tail = array[1...] // [3, 2, 1]
tailSubsequences = findAllSubsequences(tail) // recurse on tail
// Add all subsequences that don't include head
// [3,2,1] [3,1] [2,1] ...
result.addAll(tailSubsequences)
// Add all subsequences that do include head
// [4,3,2,1] [4,3,1] [4,2,1] ...
for each subsequence s in tailSubsequences
result.add(head concatenated with s)
return result
}
Upvotes: 1