在C中生成“范围内”随机数

我需要生成[0,10]范围内的随机数,这样:

  • 所有数字都出现一次。
  • 没有重复的结果。

有人可以指导我使用哪种算法?

Richard J. Ross的答案中的算法是错误的。 它生成n^n可能的排序而不是n! 。 Jeff Atwood的博客上的这篇文章说明了这个问题: http : //www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html

相反,你应该使用Knuth-Fisher-Yates Shuffle:

 int values[11] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; srand(time(NULL)); for (int i = 10; i > 0; i--) { int n = rand() % (i + 1); int temp = values[n]; values[n] = values[i]; values[i] = temp; } 

尝试这个算法的伪随机数:

 int values[11] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; srand(time(NULL)); for (int i = 0; i < 11; i++) { int swap1idx = rand() % 11; int swap2idx = rand() % 11; int tmp = values[swap1idx]; values[swap1idx] = values[swap2idx]; values[swap2idx] = tmp; } // now you can iterate through the shuffled values array. 

请注意,这受到模偏差的影响,但它应该适合您的需要。

尝试创建一个随机函数,如下所示:

 void randomize(int v[], int size, int r_max) { int i,j,flag; v[0] = 0 + rand() % r_max; // start + rand() % end /* the following cycle manages, discarding it, the case in which a number who has previously been extracted, is re-extracted. */ for(i = 1; i < size; i++) { do { v[i]= 0 + rand() % r_max; for(j=0; j 

然后,只需调用它传递一个11个元素的数组v[] ,它的大小和上限:

 randomize(v, 11, 11); 

由于它是作为参数通过引用传递的事实,该数组将被随机化,没有重复和数字出现一次。

记得打电话给srand(time(0)); 在调用randomize之前,初始化int v[11]={0,1,2,3,4,5,6,7,8,9,10};