How can I use the rand() function to generate a di

2019-09-25 07:14发布

// What I mean by this is shown by my example:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int i;
int a;


for (a = 0;a <10;a ++) {
    i = (rand()%10)+1; // generates a number from 1-10
    printf("%d\n", i);
}

// I would like for the loop to generate a number that gives a number that was not generated before. For example, an output such as:

1,3,6,2,8,9,4,10,5,7

instead of:

3,9,10,3,7,9,2,7,10,1

In other words, I would like no copies.

标签: c random
2条回答
兄弟一词,经得起流年.
2楼-- · 2019-09-25 08:01

The idea shown in the question is to print numbers within a range, without repetition. Here is one way to do that, by putting each value into an array and swapping its elements around.

A variation could be that you don't want to use all the possible numbers, in that case just change PICKED.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ARRLEN 10
#define PICKED 10

int main(void) { 
    int array[ARRLEN];

    srand((unsigned)time(NULL));        // seed the PRNG

    for(int i = 0; i < ARRLEN; i++) {       // generate the numbers
        array[i] = i + 1;
    }

    for(int i = 0; i < ARRLEN; i++) {       // shuffle the array
        int index = rand() % ARRLEN;
        int temp = array[i];
        array[i] = array[index];        // by randomly swapping
        array[index] = temp;
    }

    for(int i = 0; i < PICKED; i++) {       // output the numbers
        printf("%d ",  array[i]);
    }
    printf("\n");
}

Program output:

9 8 4 5 1 10 7 3 6 2

The library's PRNG is not very random, but for many cases that is not important. If it is, better algorithms are available.

查看更多
beautiful°
3楼-- · 2019-09-25 08:02

You obviously don't just want no copies, but you want every number in a given set exactly once. This is, as commented by Robert, similar to shuffling a deck of cards. You don't have "decks" in C, but you can model one as an array:

int deck[] = {1,1,1,1,1,1,1,1,1,1};

This should represent 10 different "cards" (identified by their index in the array), each available one time. Now, just write code that "draws" cards:

int i = 0;  // starting point for searching for the next card to draw
for (int n = 10; n > 0; --n)  // how many cards are left
{
    int skip = rand() % n;  // randomly skip 0 .. n cards
    while (1)
    {
        if (deck[i])             // card still available?
        {
            if (!skip) break;    // none more to skip -> done
            --skip;              // else one less to skip
        }

        if (++i > 9) i = 0;      // advance index, wrapping around to 0
    }
    deck[i] = 0;              // draw the card
    printf("%d\n", i+1);      // and print it out
}

of course, seed the PRNG (e.g. srand(time(0))) first, so you don't get the same sequence every time.

查看更多
登录 后发表回答