How to resolve the algorithm Combinations step by step in the C programming language

Published on 7 June 2024 03:52 AM
#C

How to resolve the algorithm Combinations step by step in the C programming language

Table of Contents

Problem Statement

Given non-negative integers   m   and   n,   generate all size   m   combinations   of the integers from   0   (zero)   to   n-1   in sorted order   (each combination is sorted and the entire table is sorted).

3   comb   5     is: If it is more "natural" in your language to start counting from   1   (unity) instead of   0   (zero), the combinations can be of the integers from   1   to   n.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Combinations step by step in the C programming language

The provided C code implements the combination algorithm to generate and print all possible combinations of a given number of elements. A combination is a selection of items from a set that has a defined order and allows repetition.

Here's a detailed explanation of both code implementations:

First Implementation:

  • Type Marker Stick: A marker datatype is defined as an unsigned long integer. Each bit in the marker represents a choice. For example, if the marker is 0b1011, it means the first, third, and fourth elements are chosen.

  • comb Function:

    • The comb function takes four parameters:
      • pool: The total number of elements to choose from.
      • need: The number of elements to choose.
      • chosen: A marker representing the currently chosen elements.
      • at: The current position in the loop.
    • The function recursively generates all possible combinations of need elements from the pool. It uses backtracking to explore different choices.
    • If there are not enough elements left (pool < need + at), the function returns.
    • If the desired number of elements have been chosen (need == 0), the function prints the current combination.
    • If the current element is not chosen, the function recursively calls itself with the next element (comb(pool, need, chosen, at + 1)).
    • If the current element is chosen, the function recursively calls itself with the next element and the updated chosen marker to indicate the choice (comb(pool, need - 1, chosen | (one << at), at + 1)).
  • main Function:

    • Calls the comb function with pool = 5 and need = 3 to generate and print all combinations of 3 elements from a pool of 5.

Second Implementation:

  • comb Function:

    • The second implementation of the comb function uses an array c of unsigned char to store the combinations.
    • It initializes the array with the largest possible combination (e.g., for m = 5 and n = 3, c = {3, 2, 1}).
    • It then generates subsequent combinations by incrementing the elements in the array until they reach their maximum value.
    • If the largest element in the array reaches its maximum value, it increments the next-largest element and resets the smaller elements.
    • The function prints the combinations as it generates them.
  • main Function:

    • Calls the comb function with m = 5 and n = 3 to generate and print all combinations of 3 elements from a pool of 5.

Both implementations produce the same output:

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

Source code in the c programming language

#include <stdio.h>

/* Type marker stick: using bits to indicate what's chosen.  The stick can't
 * handle more than 32 items, but the idea is there; at worst, use array instead */
typedef unsigned long marker;
marker one = 1;

void comb(int pool, int need, marker chosen, int at)
{
	if (pool < need + at) return; /* not enough bits left */

	if (!need) {
		/* got all we needed; print the thing.  if other actions are
		 * desired, we could have passed in a callback function. */
		for (at = 0; at < pool; at++)
			if (chosen & (one << at)) printf("%d ", at);
		printf("\n");
		return;
	}
	/* if we choose the current item, "or" (|) the bit to mark it so. */
	comb(pool, need - 1, chosen | (one << at), at + 1);
	comb(pool, need, chosen, at + 1);  /* or don't choose it, go to next */
}

int main()
{
	comb(5, 3, 0, 0);
	return 0;
}


#include <stdio.h>

void comb(int m, int n, unsigned char *c)
{
	int i;
	for (i = 0; i < n; i++) c[i] = n - i;

	while (1) {
		for (i = n; i--;)
			printf("%d%c", c[i], i ? ' ': '\n');

		/* this check is not strictly necessary, but if m is not close to n,
		   it makes the whole thing quite a bit faster */
		i = 0;
		if (c[i]++ < m) continue;

		for (; c[i] >= m - i;) if (++i >= n) return;
		for (c[i]++; i; i--) c[i-1] = c[i] + 1;
	}
}

int main()
{
	unsigned char buf[100];
	comb(5, 3, buf);
	return 0;
}


  

You may also check:How to resolve the algorithm 99 bottles of beer step by step in the Janet programming language
You may also check:How to resolve the algorithm Roman numerals/Encode step by step in the Emacs Lisp programming language
You may also check:How to resolve the algorithm Cartesian product of two or more lists step by step in the Perl programming language
You may also check:How to resolve the algorithm Self-describing numbers step by step in the jq programming language
You may also check:How to resolve the algorithm Mayan numerals step by step in the Raku programming language