2

i want to generate an array of random numbers for example if the range is [0,10] then the desired output to be 2 3 5 6 4 7 8 9 0 1 ( non repeatitive )

the problem i am facing with rand() function is sometimes i get some repeated nos , i was discrete values in that range , and different order everytime i invoke.

Ps: I did go through some of the threads Generate a random double in a range Generate random numbers uniformly over an entire range in here and couldnt fine one similar mine, there is a subtle difference. expecially the latter one is pretty close

Community
  • 1
  • 1
Rahul
  • 11,129
  • 17
  • 63
  • 76
  • 1
    Your example includes a repeated '4'. As per GWW's answer: create your required range and shuffle. You could always have a longer list and take the first N elements if you want a subgroup. – winwaed Nov 13 '10 at 16:57
  • 1
    See http://stackoverflow.com/questions/3343797/is-this-c-implementation-of-fisher-yates-shuffle-correct – Steve Jessop Nov 13 '10 at 16:59
  • Is this homework? Not a problem if it is :) – pmg Nov 13 '10 at 17:26
  • firstly , its not a homework problem , actually its one of my lab work , my prof told me a totally different way which i felt was a long road to take , s – Rahul Nov 19 '10 at 06:25

5 Answers5

10

It seems more a problem of shuffling that of randomization.

A good start is the Fisher-Yates shuffle which starts with the sorted array of elements and generate a random permutation:

int size = 10;
int *elements = malloc(sizeof(int)*size);

// inizialize
for (int i = 0; i < size; ++i)
  elements[i] = i;

for (int i = size - 1; i > 0; --i) {
  // generate random index
  int w = rand()%i;
  // swap items
  int t = elements[i];
  elements[i] = elements[w];
  elements[w] = t;
}
Jack
  • 131,802
  • 30
  • 241
  • 343
  • 1
    Beware! 3 xor swapping is not suitable method here, because in case of i==w it will clear i'th element instead of doing nothing. Also floor is not needed here, because % is already integer. – Vovanium Nov 13 '10 at 17:08
  • yes, already fixed the random issue. Didn't notice the swap one, thanks :) – Jack Nov 13 '10 at 17:10
  • Now that you make me think about it, just to know: is there a way to reset vote? – Jack Nov 13 '10 at 17:11
  • Click upvote 2nd time to reset upvote. Now I +1 you for error correction. Mhhh, downvoted someone else. – Vovanium Nov 13 '10 at 17:12
  • the xor issue was a subtle thing – Jack Nov 13 '10 at 17:13
2

You will have an easier time if you start out with an array with the integers 0-9 (or whatever your range is) and then randomly shuffle it. There's an example of how to do the shuffling here.

GWW
  • 43,129
  • 11
  • 115
  • 108
  • that shuffling algo is generating the same nos when invoked .. multiple times . – Rahul Nov 13 '10 at 17:11
  • 1
    @Rahul: Read about rand(), please. It WILL generate same sequence each time. You need to seed PRNG with truly random number (like time) to get different results. – Vovanium Nov 13 '10 at 17:16
  • @Vovanium: `time` does not return "truly random number" :-) – pmg Nov 13 '10 at 17:47
  • @pmg: I mean something else than deterministic pseudorandom number. And from program's view it is really random. I you want truliest random, only quantum source may give you one. :) – Vovanium Nov 13 '10 at 17:53
1

You would basically want to randomize an array [0, 1, ..., 9]. Here's a C++ example, should be easy to transform to C:

icyrock.com
  • 27,952
  • 4
  • 66
  • 85
0

This code only for integer numbers, but I hope it will be enough. I am used the GCC for compilation and only the C standard library. Read comments for details. Your results will be has different values, but since it will be random.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h> // http://man7.org/linux/man-pages/man3/errno.3.html

#define ERROR_MIN_MORE_MAX_VALUE "Min value is more max value, returned 0"


/*
    Returns a random integer in between min (inclusive) and max (inclusive)
    Returns 0 if min > max and to write a error message.
 */
static int
random_integer(const int min, const int max) {
    if (max == min) return min;
    else if (min < max) return rand() % (max - min + 1) + min;

    // return 0 if min > max
    errno = EINVAL;
    perror(ERROR_MIN_MORE_MAX_VALUE);
    return 0;
}


/*
    Fills an array with random integer values in a range
 */
static int
random_int_array(int array[], const size_t length, const int min, const int max){
    for (int i = 0; i < length; ++i) {
        array[i] = random_integer(min, max);
    }
    return 0;
}


/*
    Print an array of integer items
 */
void
print_int_array(int array[], size_t length) {
    char ending_charapter[] = ", ";
    putchar('[');
    for (size_t i = 0; i < length; ++i) {
        printf("%d", array[i]);
        if (i < length - 1) {
            printf("%s", ending_charapter);
        }
    }
    puts("]");
}


int
main (const int argc, const char *argv[])
{
    // for get a random integer number from a system, to pass a current time to the function srand
    srand(time(NULL));

    int arr[10];

    printf("\tAn array with random values from 0 to 100\n");
    random_int_array(arr, 10, 0, 100);
    print_int_array(arr, 10);

    printf("\n\tAn array with random values from -100 to 0\n");
    random_int_array(arr, 10, -100, 0);
    print_int_array(arr, 10);

    printf("\n\tAn array with random values from -100 to 100\n");
    random_int_array(arr, 10, -100, 100);
    print_int_array(arr, 10);

    return 0;
}

Result

    An array with random values from 0 to 100
[86, 25, 98, 61, 42, 26, 87, 56, 86, 79]

    An array with random values from -100 to 0
[-33, -92, -57, -92, -6, -15, -61, -32, -75, -85]

    An array with random values from -100 to 100
[-15, -99, 54, 42, -74, 46, 6, -44, 86, -47]

Testing environment

$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 8.6 (jessie)
Release:    8.6
Codename:   jessie
$ uname -a
Linux localhost 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
PADYMKO
  • 4,217
  • 2
  • 36
  • 41
-1

+ Put all your numbers in the result array
+ from N down to 2
+ ---- shuffle N elements
+ return array

Example

fillarray(arr, 10);
for (n = 10; n > 1; n++) shufflearray(arr, n);
/* done */


Edit --- thanks downvoter! I didn't even realize I was doing too much work up there

  • Put all your numbers in the result array
  • from N down to 2
  • ---- swap element N with a random element from 1 to N
  • return array
pmg
  • 106,608
  • 13
  • 126
  • 198