How to resolve the algorithm Knuth shuffle step by step in the C programming language
How to resolve the algorithm Knuth shuffle step by step in the C programming language
Table of Contents
Problem Statement
The Knuth shuffle (a.k.a. the Fisher-Yates shuffle) is an algorithm for randomly shuffling the elements of an array.
Implement the Knuth shuffle for an integer array (or, if possible, an array of any type).
Given an array items with indices ranging from 0 to last, the algorithm can be defined as follows (pseudo-code):
(These are listed here just for your convenience; no need to demonstrate them on the page.)
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Knuth shuffle step by step in the C programming language
The provided C code defines two shuffle functions: a generic one (shuffle
) that can be used with any data type and a specialized one (shuffle_int
) that is optimized for integers.
-
Generic Shuffle Function (
shuffle
):- The
shuffle
function takes three arguments:obj
(a pointer to an array of elements),nmemb
(number of elements in the array), andsize
(size of each element in bytes). - It uses the Fisher-Yates shuffle algorithm to randomly rearrange the elements in the array.
- The algorithm maintains a pointer
n
to the unsorted portion of the array and repeatedly selects a random element from the unsorted portion to swap with the element at positionn
. - It uses the
rrand
function to generate random numbers. - The function allocates a temporary buffer
temp
to facilitate the swapping.
- The
-
Specialized Shuffle Function (
shuffle_int
):- The
shuffle_int
function is a specialized version of the genericshuffle
function that is optimized for integer data. - It uses the
irand
function to generate random indices and does not need to allocate a temporary buffer since it can directly swap integers using thetmp
variable. - This optimization can lead to improved performance compared to the generic
shuffle
function for integer arrays.
- The
-
Random Number Generation Functions:
- The
rrand
function generates a random integer between 0 andm-1
using therand
function and a floating-point conversion. - The
irand
function generates a random integer between 0 andn-1
by filtering out values that fall outside the desired range and using integer division to map the generated random number to the desired range.
- The
-
Main Function (
main
):- The
main
function demonstrates the usage of theshuffle_int
function. - It initializes an array
x
with integers from 0 to 19, prints the initial order of elements, shuffles the array usingshuffle_int
, and then prints the shuffled order.
- The
Source code in the c programming language
#include <stdlib.h>
#include <string.h>
int rrand(int m)
{
return (int)((double)m * ( rand() / (RAND_MAX+1.0) ));
}
#define BYTE(X) ((unsigned char *)(X))
void shuffle(void *obj, size_t nmemb, size_t size)
{
void *temp = malloc(size);
size_t n = nmemb;
while ( n > 1 ) {
size_t k = rrand(n--);
memcpy(temp, BYTE(obj) + n*size, size);
memcpy(BYTE(obj) + n*size, BYTE(obj) + k*size, size);
memcpy(BYTE(obj) + k*size, temp, size);
}
free(temp);
}
#include <stdio.h>
#include <stdlib.h>
/* define a shuffle function. e.g. decl_shuffle(double).
* advantage: compiler is free to optimize the swap operation without
* indirection with pointers, which could be much faster.
* disadvantage: each datatype needs a separate instance of the function.
* for a small funciton like this, it's not very big a deal.
*/
#define decl_shuffle(type) \
void shuffle_##type(type *list, size_t len) { \
int j; \
type tmp; \
while(len) { \
j = irand(len); \
if (j != len - 1) { \
tmp = list[j]; \
list[j] = list[len - 1]; \
list[len - 1] = tmp; \
} \
len--; \
} \
} \
/* random integer from 0 to n-1 */
int irand(int n)
{
int r, rand_max = RAND_MAX - (RAND_MAX % n);
/* reroll until r falls in a range that can be evenly
* distributed in n bins. Unless n is comparable to
* to RAND_MAX, it's not *that* important really. */
while ((r = rand()) >= rand_max);
return r / (rand_max / n);
}
/* declare and define int type shuffle function from macro */
decl_shuffle(int);
int main()
{
int i, x[20];
for (i = 0; i < 20; i++) x[i] = i;
for (printf("before:"), i = 0; i < 20 || !printf("\n"); i++)
printf(" %d", x[i]);
shuffle_int(x, 20);
for (printf("after: "), i = 0; i < 20 || !printf("\n"); i++)
printf(" %d", x[i]);
return 0;
}
You may also check:How to resolve the algorithm Optional parameters step by step in the OCaml programming language
You may also check:How to resolve the algorithm Count in factors step by step in the Forth programming language
You may also check:How to resolve the algorithm Least common multiple step by step in the PARI/GP programming language
You may also check:How to resolve the algorithm Validate International Securities Identification Number step by step in the Visual Basic .NET programming language
You may also check:How to resolve the algorithm Arithmetic evaluation step by step in the Oz programming language