洗牌阵列

时间:2015-02-14 16:53:28

标签: c arrays random shuffle

这个代码应该做的是洗牌一个数组,但是每当我运行它时,我得到相同的“混乱”数组(当然通过输入相同的非混乱数组)我认为{{1}部分是为了确保这一点。如果那不是它我不知道如何让它真正洗牌。

总而言之,我需要知道为什么我的代码每次都以相同的方式改组数组。

srand(time(NULL));

5 个答案:

答案 0 :(得分:2)

您需要将srand(time(NULL));移到for循环之外。

如果您看到,rand()伪随机号码生成器。 srand()用于提供种子,{/ 1}}将根据该种子生成随机数。

如果在每次调用rand()之前,每次种子时都使用相同的time(NULL)rand()的每个结果都将是相同的。

要获得所需的结果,您需要使用rand()为随机数生成器播种一次,稍后每次调用srand(),它会随机给您号。

注意:虽然这不是强制性的,但最好在rand()的末尾加上明确的return 0

答案 1 :(得分:1)

从循环中获取srand(time(NULL))。

来自srand reference

  

使用相同种子的两个不同初始化将生成   随后对兰德的调用也会产生相同的结果。

因此,对于每次迭代,您都要初始化随机数生成器并获取第一个项目,这始终是相同的。

答案 2 :(得分:1)

你误用srand,它应该只在循环之外被调用一次。这些也可能是srandrand实现在您运行的平台上可能特别糟糕,如果程序快速重新执行会导致性能不佳。

答案 3 :(得分:0)

glibc srand()手册页,其中指出:“srand()函数将其参数设置为rand()返回的新伪随机整数序列的种子。这些序列可通过调用srand重复()具有相同的种子值。“具体来说,您的程序可能违反了该条款:“..序列可以通过使用相同的种子值调用srand()来重复。”因为它可以随着时间的推移每秒播放rand()不止一次 - 导致相同的伪随机数序列。

答案 4 :(得分:0)

好的,我会回答后续问题。为什么循环中的srand()不好?

rand()函数生成一系列可接受的随机数,而根本不需要srand()。问题是它是一个固定的序列,所以每次运行程序时,你都会获得相同的“随机”数字。

srand(time(NULL))的目标是选择一个与之前任何起始值不同的起始值。 time()函数调用仅用于选择不同的起始点,缺点是结果每秒只更改一次。在同一秒内运行程序两次可能是从脚本文件或批处理作业启动的程序的问题,但通常不是从键盘或鼠标事件启动时。

因此,在循环中使用srand(time(NULL))会产生一个重大的恶意影响。每隔一个挂钟只能得到一个新的随机数。

即使你有一个高精度计时器来采样或使用:

    unsigned counter = time(NULL);
    srand(counter++);

..要选择不同的起始值,仍然存在问题。从顺序起始点选择的随机数的分布不像整个序列那样“随机”,并且对于某些发生器可能非常糟糕。如果您的起点来源足够随机,可以从srand();rand();获得良好的结果,那么您可能根本不需要rand()。您可以直接使用这些起始值!

最后,srand()会降低您的计划速度。特别是Visual C ++已经慢了rand()srand(),MinGW也使用了这个库。 (技术问题是由于将种子值存储在线程本地存储中,每次调用都需要100条指令才能找到。)但是,即使是静态链接的非线程安全版本也需要额外的调用和返回。需要。

这些是我知道在循环中不使用srand()的主要原因。大多数开发人员都会对“没必要”感到满意。