生成用C独一无二的随机数 [英] Generating unique random numbers in C

查看:301
本文介绍了生成用C独一无二的随机数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图产生10个独特的随机数在C.我有一个数组 numout [] 10号,但这到达段错误一段时间后。

芹苴code是:

  INT I,J,numout [10],randnum;无效的主要()
{
    函数srand(时间(NULL));
    对于(I = 0; I&小于10;我+ +)
    {
        numout [I] =生成();
        的printf(%d个,numout [I]);
        fflush(标准输出);
        睡眠(1);
        的printf(\\ B);
    }
}
INT产生()
{
    randnum = 1 +(INT)(RAND()* mul_val /(RAND_MAX + 1.0));
    为(J = 0; J< I; J ++)
    {
        如果(randnum == 0 || randnum == numout [J]。)
        {
            randnum =生成();
        }
    }
    返回(randnum);
}


解决方案

扔了code了,伤势严重。你需要一个洗牌的算法,不是一块code,对于重复检查旧的价值观。做你的方式最终会需要更长的时间和更长的池耗尽。混洗算法的优点在于,它不会降低为池变得更小。

下面是一张code我在回答不同的问题使用。它保持号码列表,并且当它返回一个随机您的话,其从列表中删除,递减为下一个随机选择的计

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;#定义ERR_NO_NUM -1
#定义ERR_NO_MEM -2INT myRandom(INT大小){
    INT I,N;
    静态INT numNums = 0;
    静态INT * numArr = NULL;    //与特定大小初始化。    如果(大小> = 0){
        如果(numArr!= NULL)
            免费(numArr);
        如果((numArr =的malloc(sizeof的(INT)*尺寸))== NULL)
            返回ERR_NO_MEM;
        对于(i = 0; I<大小;我++)
            numArr [我] =我;
        numNums =大小;
    }    //错误,如果没有号码池离开了。    如果(numNums == 0)
       返回ERR_NO_NUM;    //从池中获取随机数,并将其取出(RND在这
    //情况下返回0和numNums-1含)之间的一个数字。    N =兰特()%numNums;
    I = numArr [N];
    numArr [η] = numArr [numNums-1];
    numNums--;
    如果(numNums == 0){
        免费(numArr);
        numArr = 0;
    }    返回我;
}诠释主要(无效){
    INT I;    函数srand(时间(NULL));
    I = myRandom(20);
    而(ⅰ> = 0){
        的printf(数=%3D \\ n,I);
        I = myRandom(-1);
    }
    的printf(最终=%3D \\ n,I);
    返回0;
}

一个示例输出显示它在行动:

 数= 19
数= 10
数= 2
数= 15
数= 0
数= 6
数= 1
总数= 3
数= 17
数= 14
数= 12
数= 18
数= 4
数= 9
数= 7
数= 8
数= 16
数= 5
数= 11
数= 13
最终= -1

用非负池大小调用它和它建立一个新的序列并返回第一个随机值。在此之后,你可以用 1 调用它,它会从池中获取下一个随机的,唯一编号。当池耗尽,它会返回-1。

借助包含此code等答案有一个版本能够保持多个泳池,以及如果你希望能够在线程code使用此功能。

I tried generating 10 unique random numbers in C. I have an array numout[] for 10 numbers but this gets to "segmentation fault" after some time.

Tho code is:

int i,j,numout[10],randnum;

void main()
{
    srand(time(NULL));  
    for(i=0;i<10;i++)
    {
        numout[i]=generate();
        printf("%d",numout[i]);
        fflush(stdout);
        sleep(1);
        printf("\b");
    }
}
int generate()
{
    randnum=1+(int)(rand()*mul_val/(RAND_MAX+1.0));
    for(j=0;j<i;j++)
    {
        if(randnum==0 || randnum==numout[j])
        {
            randnum=generate();     
        }
    }
    return(randnum);
}

解决方案

Throw that code away, seriously. You need a shuffling algorithm, not a piece of code that checks older values for duplicates. Doing it your way will end up taking longer and longer as your pool runs out. The advantage of a shuffling algorithm is that it doesn't degrade as the pool becomes smaller.

Here's a piece of code I used in answering a different question. It maintains a list of numbers and, when it returns a random one to you, it removes it from the list and decrements the count for the next random selection.

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

#define ERR_NO_NUM -1
#define ERR_NO_MEM -2

int myRandom (int size) {
    int i, n;
    static int numNums = 0;
    static int *numArr = NULL;

    // Initialize with a specific size.

    if (size >= 0) {
        if (numArr != NULL)
            free (numArr);
        if ((numArr = malloc (sizeof(int) * size)) == NULL)
            return ERR_NO_MEM;
        for (i = 0; i  < size; i++)
            numArr[i] = i;
        numNums = size;
    }

    // Error if no numbers left in pool.

    if (numNums == 0)
       return ERR_NO_NUM;

    // Get random number from pool and remove it (rnd in this
    //   case returns a number between 0 and numNums-1 inclusive).

    n = rand() % numNums;
    i = numArr[n];
    numArr[n] = numArr[numNums-1];
    numNums--;
    if (numNums == 0) {
        free (numArr);
        numArr = 0;
    }

    return i;
}

int main (void) {
    int i;

    srand (time (NULL));
    i = myRandom (20);
    while (i >= 0) {
        printf ("Number = %3d\n", i);
        i = myRandom (-1);
    }
    printf ("Final  = %3d\n", i);
    return 0;
}

A sample output shows it in action:

Number =  19
Number =  10
Number =   2
Number =  15
Number =   0
Number =   6
Number =   1
Number =   3
Number =  17
Number =  14
Number =  12
Number =  18
Number =   4
Number =   9
Number =   7
Number =   8
Number =  16
Number =   5
Number =  11
Number =  13
Final  =  -1

Call it with a non-negative pool size and it sets up a new sequence and returns the first random value. Following that, you can call it with -1 and it will get the next random, unique number from the pool. When the pool is exhausted, it will return -1.

The other answer that contained this code has a version that can maintain multiple pools as well if you want to be able to use this function in threaded code.

这篇关于生成用C独一无二的随机数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆