I'm looking for a function in ANSI C that would randomize an array just like PHP's shuffle()
does. Is there such a function or do I have to write it on my own? And if I have to write it on my own, what's the best/most performant way to do it?
My ideas so far:
Write the function shuffle(array) that shuffles (randomly reorders) elements of the array. Multiple runs of shuffle may lead to different orders of elements. For instance: let arr = [1, 2, 3]; shuffle(arr); // arr = [3, 2, 1] shuffle(arr); // arr = [2, 1, 3] shuffle(arr); // arr = [3, 1, 2] // ...
The first and simplest way to shuffle an array in JavaScript is to provide a custom function to a . sort() . const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; const shuffledArray = array. sort((a, b) => 0.5 - Math.
The shuffle() function randomizes the order of the elements in the array. This function assigns new keys for the elements in the array.
The Fisher–Yates shuffle is an algorithm for generating a random permutation of a finite sequence—in plain terms, the algorithm shuffles the sequence.
Pasted from Asmodiel's link to Ben Pfaff's Writings, for persistence:
#include <stdlib.h> /* Arrange the N elements of ARRAY in random order. Only effective if N is much smaller than RAND_MAX; if this may not be the case, use a better random number generator. */ void shuffle(int *array, size_t n) { if (n > 1) { size_t i; for (i = 0; i < n - 1; i++) { size_t j = i + rand() / (RAND_MAX / (n - i) + 1); int t = array[j]; array[j] = array[i]; array[i] = t; } } }
EDIT: And here's a generic version that works for any type (int
, struct
, ...) through memcpy
. With an example program to run, it requires VLAs, not every compiler supports this so you might want to change that to malloc
(which will perform badly) or a static buffer large enough to accommodate any type you throw at it:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> /* compile and run with * cc shuffle.c -o shuffle && ./shuffle */ #define NELEMS(x) (sizeof(x) / sizeof(x[0])) /* arrange the N elements of ARRAY in random order. * Only effective if N is much smaller than RAND_MAX; * if this may not be the case, use a better random * number generator. */ static void shuffle(void *array, size_t n, size_t size) { char tmp[size]; char *arr = array; size_t stride = size * sizeof(char); if (n > 1) { size_t i; for (i = 0; i < n - 1; ++i) { size_t rnd = (size_t) rand(); size_t j = i + rnd / (RAND_MAX / (n - i) + 1); memcpy(tmp, arr + j * stride, size); memcpy(arr + j * stride, arr + i * stride, size); memcpy(arr + i * stride, tmp, size); } } } #define print_type(count, stmt) \ do { \ printf("["); \ for (size_t i = 0; i < (count); ++i) { \ stmt; \ } \ printf("]\n"); \ } while (0) struct cmplex { int foo; double bar; }; int main() { srand(time(NULL)); int intarr[] = { 1, -5, 7, 3, 20, 2 }; print_type(NELEMS(intarr), printf("%d,", intarr[i])); shuffle(intarr, NELEMS(intarr), sizeof(intarr[0])); print_type(NELEMS(intarr), printf("%d,", intarr[i])); struct cmplex cmparr[] = { { 1, 3.14 }, { 5, 7.12 }, { 9, 8.94 }, { 20, 1.84 } }; print_type(NELEMS(intarr), printf("{%d %f},", cmparr[i].foo, cmparr[i].bar)); shuffle(cmparr, NELEMS(cmparr), sizeof(cmparr[0])); print_type(NELEMS(intarr), printf("{%d %f},", cmparr[i].foo, cmparr[i].bar)); return 0; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With