【问题标题】:To generate array of random numbers in a given range in "C"在“C”中生成给定范围内的随机数数组
【发布时间】:2011-05-09 14:03:39
【问题描述】:

我想生成一个随机数数组,例如,如果范围是 [0,10],那么所需的输出是 2 3 5 6 4 7 8 9 0 1(不重复)

我使用 rand() 函数面临的问题是有时我会得到一些重复的 nos,我是该范围内的离散值,并且每次调用时的顺序都不同。

Ps:我确实经历了一些线程 Generate a random double in a range Generate random numbers uniformly over an entire range 在这里,不能对一个类似的地雷进行罚款,有一个微妙的区别。特别是后者非常接近

【问题讨论】:

  • 您的示例包含重复的“4”。根据 GWW 的回答:创建所需的范围并随机播放。如果你想要一个子组,你总是可以有一个更长的列表并取前 N 个元素。
  • 这是作业吗?如果是的话没问题:)
  • 首先,这不是作业问题,实际上它是我的实验室工作之一,我的教授告诉我一个完全不同的方法,我觉得这是一条很长的路要走,s

标签: c


【解决方案1】:

这似乎更像是一个随机化的洗牌问题。

Fisher-Yates shuffle 是一个好的开始,它从已排序的元素数组开始并生成随机排列:

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;
}

【讨论】:

  • 当心! 3 xor 交换在这里不是合适的方法,因为在 i==w 的情况下,它将清除第 i 个元素而不是什么都不做。这里也不需要 floor,因为 % 已经是整数了。
  • 是的,已经修复了随机问题。没有注意到交换一个,谢谢:)
  • 既然你让我想了想,只是想知道:有没有办法重置投票?
  • 第二次点击点赞重置点赞。现在我 +1 你来纠正错误。嗯,否决了其他人。
  • xor 问题很微妙
【解决方案2】:

如果您从包含整数 0-9(或任何您的范围)的数组开始,然后随机打乱它,您会更轻松。有一个如何洗牌的例子here。

【讨论】:

  • 洗牌算法在被调用时会生成相同的编号.. 多次。
  • @Rahul:请阅读有关 rand() 的信息。它每次都会生成相同的序列。您需要使用真正的随机数(如时间)播种 PRNG 以获得不同的结果。
  • @Vovanium: time 不返回“真正的随机数”:-)
  • @pmg:我的意思不是确定性伪随机数。从程序的角度来看,它确实是随机的。我你想要最真实的随机,只有量子源可以给你一个。 :)
【解决方案3】:

您基本上想要随机化一个数组 [0, 1, ..., 9]。这是一个 C++ 示例,应该很容易转换为 C:

【讨论】:

    【解决方案4】:

    此代码仅适用于整数,但我希望它足够了。我使用 GCC 进行编译,并且只使用 C 标准库。阅读 cmets 了解详情。您的结果将具有不同的值,但因为它是随机的。

    #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;
    }
    

    结果

        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]
    

    测试环境

    $ 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.
    

    【讨论】:

      【解决方案5】:

      + 将所有数字放入结果数组
      + 从 N 到 2
      + ---- 随机播放 N 个元素
      + 返回数组

      例子

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


      编辑 --- 感谢downvoter!我什至没有意识到我在那里做了太多的工作

      • 将所有数字放入结果数组中
      • 从 N 到 2
      • ---- 将元素 N 与从 1 到 N 的随机元素交换
      • 返回数组

      【讨论】:

        猜你喜欢
        • 2014-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-27
        • 1970-01-01
        • 1970-01-01
        • 2016-05-04
        相关资源
        最近更新 更多